Skip to content

Commit edd31bd

Browse files
Merge pull request #23 from contentstack/next
Fixed Semgrep issues
2 parents bef5265 + b9dccb1 commit edd31bd

File tree

7 files changed

+66
-33
lines changed

7 files changed

+66
-33
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
## Change log
22

3+
### Version: 4.0.4
4+
#### Date: July-10-2024
5+
Fixed semgrep issues
6+
37
### Version: 4.0.3
48
#### Date: June-11-2024
59
Fixed region issue

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@contentstack/delivery-sdk",
3-
"version": "4.0.3",
3+
"version": "4.0.4",
44
"type": "commonjs",
55
"main": "./dist/cjs/src/index.js",
66
"types": "./dist/types/src/index.d.ts",

src/lib/query.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import { BaseQuery } from './base-query';
33
import { BaseQueryParameters, QueryOperation, QueryOperator, TaxonomyQueryOperation } from './types';
44
import { params, queryParams } from './internal-types';
55

6+
const safePatterns: RegExp[] = [
7+
/^[a-zA-Z0-9_.-]+$/, // Alphanumeric with underscores, periods, and dashes
8+
];
9+
610
export class Query extends BaseQuery {
711
private _contentTypeUid?: string;
812

@@ -23,19 +27,15 @@ export class Query extends BaseQuery {
2327
const alphanumericRegex = /^[a-zA-Z0-9_.-]+$/;
2428
return alphanumericRegex.test(input);
2529
}
26-
// Validate if input is a valid regex pattern
30+
31+
// Validate if input matches any of the safe, pre-approved patterns
2732
private isValidRegexPattern(input: string): boolean {
28-
try {
29-
RegExp(input)
30-
return true;
31-
}
32-
catch {
33+
if (!this.isValidAlphanumeric(input)) {
3334
return false;
3435
}
35-
36+
return safePatterns.some(pattern => pattern.test(input));
3637
}
3738

38-
// Validate if value is an array of strings, numbers, or booleans
3939
private isValidValue(value: any[]): boolean {
4040
return Array.isArray(value) && value.every(item => typeof item === 'string' || typeof item === 'number' || typeof item === 'boolean');
4141
}

test/unit/contenttype-query.spec.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,15 @@ import MockAdapter from 'axios-mock-adapter';
44
import { HOST_URL } from '../utils/constant';
55
import { contentTypeQueryFindResponseDataMock } from '../utils/mocks';
66
import axios, { Axios } from 'axios';
7+
import { MOCK_CLIENT_OPTIONS } from '../utils/constant';
78

89
describe('ContentTypeQuery class', () => {
910
let contentTypeQuery: ContentTypeQuery;
1011
let client: AxiosInstance;
1112
let mockClient: MockAdapter;
12-
let clientConfig: HttpClientParams;
1313

1414
beforeAll(() => {
15-
clientConfig = {
16-
apiKey: 'API_KEY',
17-
accessToken: 'DELIVERY_TOKEN',
18-
};
19-
client = httpClient(clientConfig);
15+
client = httpClient(MOCK_CLIENT_OPTIONS);
2016
mockClient = new MockAdapter(client as any);
2117
});
2218

test/unit/taxonomy-query.spec.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,14 @@ import { TaxonomyQuery } from "../../src/lib/taxonomy-query";
22
import { AxiosInstance, HttpClientParams, httpClient } from "@contentstack/core";
33
import MockAdapter from 'axios-mock-adapter';
44
import { QueryOperation, QueryOperator, TaxonomyQueryOperation } from "../../src/lib/types";
5+
import { MOCK_CLIENT_OPTIONS } from '../utils/constant';
56

67
describe("Taxonomy-query class", () => {
78
let taxonomyQuery: TaxonomyQuery;
89
let client: AxiosInstance;
9-
let clientConfig: HttpClientParams;
1010

1111
beforeAll(() => {
12-
clientConfig = {
13-
apiKey: 'API_KEY',
14-
accessToken: 'DELIVERY_TOKEN',
15-
};
16-
client = httpClient(clientConfig);
12+
client = httpClient(MOCK_CLIENT_OPTIONS);
1713
})
1814

1915
beforeEach(() => {

tools/cleanup.js

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,65 @@
11
const fs = require('fs');
22
const path = require('path');
3-
/* eslint-enable */
3+
4+
// To remove the relative path
5+
function sanitizePath(str) {
6+
return str ? str.replace(/^(\.\.(\/|\\|$))+/, '') : str;
7+
}
8+
9+
10+
function validateAndSanitize(input) {
11+
// Allow only alphanumeric characters, dashes, underscores, and dots for file extensions
12+
return input.replace(/[^a-zA-Z0-9-_\.]/g, '');
13+
}
14+
15+
function ensureSafePath(basePath, targetPath) {
16+
const resolvedBase = path.resolve(basePath);
17+
const resolvedTarget = path.resolve(basePath, targetPath);
18+
19+
// console.log('Base Path:', resolvedBase);
20+
// console.log('Target Path:', resolvedTarget);
21+
22+
if (resolvedTarget.indexOf(resolvedBase) !== 0) {
23+
throw new Error(`Unsafe path detected: ${resolvedTarget} is not within ${resolvedBase}`);
24+
}
25+
26+
return resolvedTarget;
27+
}
428

529
const deleteFolderRecursive = (_path) => {
30+
// console.log('Attempting to delete:', _path);
31+
632
if (fs.existsSync(_path)) {
7-
fs.readdirSync(_path).forEach((file) => {
8-
const curPath = path.join(_path, file);
33+
const sanitizedPath = sanitizePath(_path);
34+
fs.readdirSync(sanitizedPath).forEach((file) => {
35+
const sanitizedFile = validateAndSanitize(file);
36+
const curPath = ensureSafePath(_path, sanitizedFile);
37+
38+
// console.log('Deleting:', curPath);
39+
940
if (fs.lstatSync(curPath).isDirectory()) {
1041
deleteFolderRecursive(curPath);
1142
} else {
1243
fs.unlinkSync(curPath);
1344
}
1445
});
1546
fs.rmdirSync(_path);
47+
} else {
48+
console.log('Path does not exist:', _path);
1649
}
1750
};
1851

52+
const rootDir = path.resolve(__dirname, '..'); // Set the base path to the root of the project
1953
const folder = process.argv.slice(2)[0];
54+
const sanitizedFolder = folder ? validateAndSanitize(folder) : null;
2055

21-
if (folder) {
22-
deleteFolderRecursive(path.join(__dirname, '../dist', folder));
56+
if (sanitizedFolder) {
57+
// console.log('Sanitized folder:', sanitizedFolder);
58+
deleteFolderRecursive(ensureSafePath(rootDir, path.join('dist', sanitizedFolder)));
2359
} else {
24-
deleteFolderRecursive(path.join(__dirname, '../dist/cjs'));
25-
deleteFolderRecursive(path.join(__dirname, '../dist/esm'));
26-
deleteFolderRecursive(path.join(__dirname, '../dist/umd'));
27-
deleteFolderRecursive(path.join(__dirname, '../dist/types'));
28-
}
60+
// console.log('No folder specified, deleting default directories...');
61+
deleteFolderRecursive(ensureSafePath(rootDir, 'dist/cjs'));
62+
deleteFolderRecursive(ensureSafePath(rootDir, 'dist/esm'));
63+
deleteFolderRecursive(ensureSafePath(rootDir, 'dist/umd'));
64+
deleteFolderRecursive(ensureSafePath(rootDir, 'dist/types'));
65+
}

0 commit comments

Comments
 (0)