Browse Source

Merge pull request #6114 from nocodb/develop

pull/6115/head 0.109.6
github-actions[bot] 1 year ago committed by GitHub
parent
commit
e2cde1c33b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 52
      packages/nc-gui/package-lock.json
  2. 2
      packages/nc-gui/package.json
  3. 4
      packages/nocodb-sdk/package-lock.json
  4. 30
      packages/nocodb/package-lock.json
  5. 2
      packages/nocodb/package.json
  6. 2
      packages/nocodb/src/helpers/webhookHelpers.ts
  7. 38
      packages/nocodb/src/plugins/storage/Local.ts

52
packages/nc-gui/package-lock.json generated

@ -30,7 +30,7 @@
"leaflet.markercluster": "^1.5.3",
"locale-codes": "^1.3.1",
"monaco-editor": "^0.33.0",
"nocodb-sdk": "0.109.5",
"nocodb-sdk": "file:../nocodb-sdk",
"papaparse": "^5.3.2",
"pinia": "^2.0.33",
"qrcode": "^1.5.1",
@ -111,7 +111,6 @@
},
"../nocodb-sdk": {
"version": "0.109.5",
"extraneous": true,
"license": "AGPL-3.0-or-later",
"dependencies": {
"axios": "^0.21.1",
@ -8720,6 +8719,7 @@
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
"integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==",
"devOptional": true,
"funding": [
{
"type": "individual",
@ -12238,21 +12238,8 @@
}
},
"node_modules/nocodb-sdk": {
"version": "0.109.5",
"resolved": "https://registry.npmjs.org/nocodb-sdk/-/nocodb-sdk-0.109.5.tgz",
"integrity": "sha512-CGrTADus9bfUJ5qHcMqRN3OYwOmkRm7iRml54lXmE36WoxACQs/ACWi7OQkzDSsSpduPitHis0a0n83AmlBVYw==",
"dependencies": {
"axios": "^0.21.1",
"jsep": "^1.3.6"
}
},
"node_modules/nocodb-sdk/node_modules/axios": {
"version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"dependencies": {
"follow-redirects": "^1.14.0"
}
"resolved": "../nocodb-sdk",
"link": true
},
"node_modules/node-abi": {
"version": "3.23.0",
@ -24729,7 +24716,8 @@
"follow-redirects": {
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
"integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA=="
"integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==",
"devOptional": true
},
"form-data": {
"version": "4.0.0",
@ -27279,22 +27267,22 @@
}
},
"nocodb-sdk": {
"version": "0.109.5",
"resolved": "https://registry.npmjs.org/nocodb-sdk/-/nocodb-sdk-0.109.5.tgz",
"integrity": "sha512-CGrTADus9bfUJ5qHcMqRN3OYwOmkRm7iRml54lXmE36WoxACQs/ACWi7OQkzDSsSpduPitHis0a0n83AmlBVYw==",
"version": "file:../nocodb-sdk",
"requires": {
"@typescript-eslint/eslint-plugin": "^4.0.1",
"@typescript-eslint/parser": "^4.0.1",
"axios": "^0.21.1",
"jsep": "^1.3.6"
},
"dependencies": {
"axios": {
"version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"requires": {
"follow-redirects": "^1.14.0"
}
}
"cspell": "^4.1.0",
"eslint": "^7.8.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-functional": "^3.0.2",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-prettier": "^4.0.0",
"jsep": "^1.3.6",
"npm-run-all": "^4.1.5",
"prettier": "^2.1.1",
"typescript": "^4.0.2"
}
},
"node-abi": {

2
packages/nc-gui/package.json

@ -54,7 +54,7 @@
"leaflet.markercluster": "^1.5.3",
"locale-codes": "^1.3.1",
"monaco-editor": "^0.33.0",
"nocodb-sdk": "0.109.5",
"nocodb-sdk": "file:../nocodb-sdk",
"papaparse": "^5.3.2",
"pinia": "^2.0.33",
"qrcode": "^1.5.1",

4
packages/nocodb-sdk/package-lock.json generated

@ -1,12 +1,12 @@
{
"name": "nocodb-sdk",
"version": "0.109.4",
"version": "0.109.5",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "nocodb-sdk",
"version": "0.109.4",
"version": "0.109.5",
"license": "AGPL-3.0-or-later",
"dependencies": {
"axios": "^0.21.1",

30
packages/nocodb/package-lock.json generated

@ -83,7 +83,7 @@
"nc-lib-gui": "0.109.5",
"nc-plugin": "^0.1.3",
"ncp": "^2.0.0",
"nocodb-sdk": "0.109.5",
"nocodb-sdk": "file:../nocodb-sdk",
"nodemailer": "^6.4.10",
"object-hash": "^3.0.0",
"object-sizeof": "^2.6.1",
@ -192,7 +192,6 @@
},
"../nocodb-sdk": {
"version": "0.109.5",
"extraneous": true,
"license": "AGPL-3.0-or-later",
"dependencies": {
"axios": "^0.21.1",
@ -13208,13 +13207,8 @@
}
},
"node_modules/nocodb-sdk": {
"version": "0.109.5",
"resolved": "https://registry.npmjs.org/nocodb-sdk/-/nocodb-sdk-0.109.5.tgz",
"integrity": "sha512-CGrTADus9bfUJ5qHcMqRN3OYwOmkRm7iRml54lXmE36WoxACQs/ACWi7OQkzDSsSpduPitHis0a0n83AmlBVYw==",
"dependencies": {
"axios": "^0.21.1",
"jsep": "^1.3.6"
}
"resolved": "../nocodb-sdk",
"link": true
},
"node_modules/node-abort-controller": {
"version": "3.1.1",
@ -28517,12 +28511,22 @@
"integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg=="
},
"nocodb-sdk": {
"version": "0.109.5",
"resolved": "https://registry.npmjs.org/nocodb-sdk/-/nocodb-sdk-0.109.5.tgz",
"integrity": "sha512-CGrTADus9bfUJ5qHcMqRN3OYwOmkRm7iRml54lXmE36WoxACQs/ACWi7OQkzDSsSpduPitHis0a0n83AmlBVYw==",
"version": "file:../nocodb-sdk",
"requires": {
"@typescript-eslint/eslint-plugin": "^4.0.1",
"@typescript-eslint/parser": "^4.0.1",
"axios": "^0.21.1",
"jsep": "^1.3.6"
"cspell": "^4.1.0",
"eslint": "^7.8.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-functional": "^3.0.2",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-prettier": "^4.0.0",
"jsep": "^1.3.6",
"npm-run-all": "^4.1.5",
"prettier": "^2.1.1",
"typescript": "^4.0.2"
}
},
"node-abort-controller": {

2
packages/nocodb/package.json

@ -116,7 +116,7 @@
"nc-lib-gui": "0.109.5",
"nc-plugin": "^0.1.3",
"ncp": "^2.0.0",
"nocodb-sdk": "0.109.5",
"nocodb-sdk": "file:../nocodb-sdk",
"nodemailer": "^6.4.10",
"object-hash": "^3.0.0",
"object-sizeof": "^2.6.1",

2
packages/nocodb/src/helpers/webhookHelpers.ts

@ -271,7 +271,7 @@ export async function invokeWebhook(
return;
}
if (hook.condition) {
if (hook.condition && !testHook) {
if (isBulkOperation) {
const filteredData = [];
for (const data of newData) {

38
packages/nocodb/src/plugins/storage/Local.ts

@ -3,6 +3,7 @@ import path from 'path';
import { promisify } from 'util';
import mkdirp from 'mkdirp';
import axios from 'axios';
import { NcError } from '../../helpers/catchError';
import { getToolDir } from '../../utils/nc-config';
import type { IStorageAdapterV2, XcFile } from 'nc-plugin';
import type { Readable } from 'stream';
@ -11,7 +12,7 @@ export default class Local implements IStorageAdapterV2 {
constructor() {}
public async fileCreate(key: string, file: XcFile): Promise<any> {
const destPath = path.join(getToolDir(), ...key.split('/'));
const destPath = this.validateAndNormalisePath(key);
try {
await mkdirp(path.dirname(destPath));
const data = await promisify(fs.readFile)(file.path);
@ -24,7 +25,7 @@ export default class Local implements IStorageAdapterV2 {
}
async fileCreateByUrl(key: string, url: string): Promise<any> {
const destPath = path.join(getToolDir(), ...key.split('/'));
const destPath = this.validateAndNormalisePath(key);
return new Promise((resolve, reject) => {
axios
.get(url, {
@ -71,7 +72,7 @@ export default class Local implements IStorageAdapterV2 {
stream: Readable,
): Promise<void> {
return new Promise((resolve, reject) => {
const destPath = path.join(getToolDir(), ...key.split('/'));
const destPath = this.validateAndNormalisePath(key);
try {
mkdirp(path.dirname(destPath)).then(() => {
const writableStream = fs.createWriteStream(destPath);
@ -86,12 +87,12 @@ export default class Local implements IStorageAdapterV2 {
}
public async fileReadByStream(key: string): Promise<Readable> {
const srcPath = path.join(getToolDir(), ...key.split('/'));
const srcPath = this.validateAndNormalisePath(key);
return fs.createReadStream(srcPath, { encoding: 'utf8' });
}
public async getDirectoryList(key: string): Promise<string[]> {
const destDir = path.join(getToolDir(), ...key.split('/'));
const destDir = this.validateAndNormalisePath(key);
return fs.promises.readdir(destDir);
}
@ -103,7 +104,7 @@ export default class Local implements IStorageAdapterV2 {
public async fileRead(filePath: string): Promise<any> {
try {
const fileData = await fs.promises.readFile(
path.join(getToolDir(), ...filePath.split('/')),
this.validateAndNormalisePath(filePath, true),
);
return fileData;
} catch (e) {
@ -118,4 +119,29 @@ export default class Local implements IStorageAdapterV2 {
test(): Promise<boolean> {
return Promise.resolve(false);
}
// method for validate/normalise the path for avoid path traversal attack
protected validateAndNormalisePath(
fileOrFolderPath: string,
throw404 = false,
): string {
// Get the absolute path to the base directory
const absoluteBasePath = path.resolve(getToolDir(), 'nc');
// Get the absolute path to the file
const absolutePath = path.resolve(
path.join(getToolDir(), ...fileOrFolderPath.split('/')),
);
// Check if the resolved path is within the intended directory
if (!absolutePath.startsWith(absoluteBasePath)) {
if (throw404) {
NcError.notFound();
} else {
NcError.badRequest('Invalid path');
}
}
return absolutePath;
}
}

Loading…
Cancel
Save