Skip to content

Commit b717f8f

Browse files
authored
Merge pull request #56 from contentstack/fix/cs-43093-vulnerable-functions
Fix/cs 43093 vulnerable functions
2 parents 6362eea + 9129221 commit b717f8f

File tree

5 files changed

+246
-20
lines changed

5 files changed

+246
-20
lines changed

package-lock.json

Lines changed: 183 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: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"@babel/preset-env": "^7.22.20",
4040
"@commitlint/cli": "^17.7.1",
4141
"@commitlint/config-conventional": "^17.7.0",
42+
"@types/dompurify": "^3.0.5",
4243
"@types/jest": "^26.0.24",
4344
"babel-core": "^4.7.16",
4445
"babel-jest": "^29.7.0",
@@ -48,8 +49,8 @@
4849
"eslint": "^8.50.0",
4950
"husky": "^8.0.3",
5051
"jest": "^29.7.0",
51-
"jest-environment-jsdom": "^29.7.0",
5252
"jest-coverage-badges": "^1.1.2",
53+
"jest-environment-jsdom": "^29.7.0",
5354
"jest-html-reporters": "^2.1.7",
5455
"jest-junit": "^15.0.0",
5556
"jsdom": "^21.1.2",
@@ -80,5 +81,9 @@
8081
"presets": [
8182
"es2015"
8283
]
84+
},
85+
"dependencies": {
86+
"cheerio": "^1.0.0-rc.12",
87+
"dompurify": "^3.1.1"
8388
}
8489
}

src/helper/regex-match.ts

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,27 @@
1-
const FigureTagRegex = /<\s*figure[^>]*>([^]*?)<\s*\/\s*figure>/g;
2-
31
export function containsFigureTag(content: string): boolean {
4-
return countFigureTags(content) > 0;
2+
const openingTag = '<figure';
3+
const closingTag = '</figure>';
4+
const openingIndex = content.indexOf(openingTag);
5+
const closingIndex = content.indexOf(closingTag);
6+
return openingIndex !== -1 && closingIndex !== -1 && closingIndex > openingIndex;
57
}
68

7-
export function matchFigureTag(content: string): RegExpMatchArray {
8-
return content.match(FigureTagRegex);
9+
export function matchFigureTag(content: string): string[] | null {
10+
const matches: string[] = [];
11+
const openingTag = '<figure';
12+
const closingTag = '</figure>';
13+
let startIndex = 0;
14+
while ((startIndex = content.indexOf(openingTag, startIndex)) !== -1) {
15+
const endIndex = content.indexOf(closingTag, startIndex);
16+
if (endIndex !== -1 && endIndex > startIndex) {
17+
matches.push(content.substring(startIndex, endIndex + closingTag.length));
18+
startIndex = endIndex + closingTag.length;
19+
} else {
20+
console.error('Malformed figure tag found in content');
21+
break;
22+
}
23+
}
24+
return matches.length > 0 ? matches : null;
925
}
1026

1127
export function countFigureTags(content: string): number {

src/options/default-node-options.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Next, RenderOption } from ".";
22
import MarkType from "../nodes/mark-type";
33
import Node from "../nodes/node";
44
import NodeType from "../nodes/node-type";
5+
import * as DOMPurify from 'dompurify';
56

67
export const defaultNodeOption: RenderOption = {
78
[NodeType.DOCUMENT]:(node: Node) => {
@@ -11,16 +12,19 @@ export const defaultNodeOption: RenderOption = {
1112
return `<p${node.attrs.style ? ` style="${node.attrs.style}"` : ``}${node.attrs.class ? ` class="${node.attrs.class}"` : ``}${node.attrs.id ? ` id="${node.attrs.id}"` : ``}>${next(node.children)}</p>`
1213
},
1314
[NodeType.LINK]:(node: Node, next: Next) => {
15+
const sanitizedHref = DOMPurify.sanitize(node.attrs.href || node.attrs.url);
1416
if (node.attrs.target) {
15-
return `<a${node.attrs.style ? ` style="${node.attrs.style}"` : ``}${node.attrs.class ? ` class="${node.attrs.class}"` : ``}${node.attrs.id ? ` id="${node.attrs.id}"` : ``} href="${node.attrs.href || node.attrs.url}" target="${node.attrs.target}">${next(node.children)}</a>`
17+
return `<a${node.attrs.style ? ` style="${node.attrs.style}"` : ``}${node.attrs.class ? ` class="${node.attrs.class}"` : ``}${node.attrs.id ? ` id="${node.attrs.id}"` : ``} href="${sanitizedHref}" target="${node.attrs.target}">${next(node.children)}</a>`
1618
}
17-
return `<a${node.attrs.style ? ` style="${node.attrs.style}"` : ``}${node.attrs.class ? ` class="${node.attrs.class}"` : ``}${node.attrs.id ? ` id="${node.attrs.id}"` : ``} href="${node.attrs.href || node.attrs.url}">${next(node.children)}</a>`
19+
return `<a${node.attrs.style ? ` style="${node.attrs.style}"` : ``}${node.attrs.class ? ` class="${node.attrs.class}"` : ``}${node.attrs.id ? ` id="${node.attrs.id}"` : ``} href="${sanitizedHref}">${next(node.children)}</a>`
1820
},
1921
[NodeType.IMAGE]:(node: Node, next: Next) => {
20-
return `<img${node.attrs.style ? ` style="${node.attrs.style}"` : ``}${node.attrs.class ? ` class="${node.attrs.class}"` : ``}${node.attrs.id ? ` id="${node.attrs.id}"` : ``} src="${node.attrs.src || node.attrs.url}" />${next(node.children)}`
22+
const sanitizedSrc = DOMPurify.sanitize(node.attrs.src || node.attrs.url);
23+
return `<img${node.attrs.style ? ` style="${node.attrs.style}"` : ``}${node.attrs.class ? ` class="${node.attrs.class}"` : ``}${node.attrs.id ? ` id="${node.attrs.id}"` : ``} src="${sanitizedSrc}" />${next(node.children)}`
2124
},
2225
[NodeType.EMBED]:(node: Node, next: Next) => {
23-
return `<iframe${node.attrs.style ? ` style="${node.attrs.style}"` : ``}${node.attrs.class ? ` class="${node.attrs.class}"` : ``}${node.attrs.id ? ` id="${node.attrs.id}"` : ``} src="${node.attrs.src || node.attrs.url}">${next(node.children)}</iframe>`
26+
const sanitizedSrc = DOMPurify.sanitize(node.attrs.src || node.attrs.url);
27+
return `<iframe${node.attrs.style ? ` style="${node.attrs.style}"` : ``}${node.attrs.class ? ` class="${node.attrs.class}"` : ``}${node.attrs.id ? ` id="${node.attrs.id}"` : ``} src="${sanitizedSrc}">${next(node.children)}</iframe>`
2428
},
2529
[NodeType.HEADING_1]:(node: Node, next: Next) => {
2630
return `<h1${node.attrs.style ? ` style="${node.attrs.style}"` : ``}${node.attrs.class ? ` class="${node.attrs.class}"` : ``}${node.attrs.id ? ` id="${node.attrs.id}"` : ``}>${next(node.children)}</h1>`
@@ -84,8 +88,9 @@ export const defaultNodeOption: RenderOption = {
8488
},
8589

8690
['reference']:(node: Node, next: Next) => {
91+
const sanitizedAsset = DOMPurify.sanitize(node.attrs['asset-link']);
8792
if (node.attrs.type === 'asset') {
88-
return `<img${node.attrs.style ? ` style="${node.attrs.style}"` : ``}${node.attrs.class ? ` class="${node.attrs.class}"` : ``}${node.attrs.id ? ` id="${node.attrs.id}"` : ``} src="${node.attrs['asset-link']}" />`
93+
return `<img${node.attrs.style ? ` style="${node.attrs.style}"` : ``}${node.attrs.class ? ` class="${node.attrs.class}"` : ``}${node.attrs.id ? ` id="${node.attrs.id}"` : ``} src="${sanitizedAsset}" />`
8994
}
9095
return ``
9196
},

0 commit comments

Comments
 (0)