Skip to content

Commit

Permalink
Fix ReDoS vulnerability
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed Mar 11, 2021
1 parent 3c99615 commit 01f8a08
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 2 deletions.
12 changes: 10 additions & 2 deletions index.js
Expand Up @@ -21,9 +21,17 @@ const cleanEntities = svg => {
return svg.replace(entityRegex, '');
};

const regex = /^\s*(?:<\?xml[^>]*>\s*)?(?:<!doctype svg[^>]*\s*(?:\[?(?:\s*<![^>]*>\s*)*\]?)*[^>]*>\s*)?(?:<svg[^>]*>[^]*<\/svg>|<svg[^/>]*\/\s*>)\s*$/i;
const removeDtdMarkupDeclarations = svg => svg.replace(/\[?(?:\s*<![A-Z]+[^>]*>\s*)*\]?/g, '');

const isSvg = input => Boolean(input) && !isBinary(input) && regex.test(cleanEntities(input.toString()).replace(htmlCommentRegex, ''));
const clean = svg => {
svg = cleanEntities(svg);
svg = removeDtdMarkupDeclarations(svg);
return svg;
};

const regex = /^\s*(?:<\?xml[^>]*>\s*)?(?:<!doctype svg[^>]*>\s*)?(?:<svg[^>]*>[^]*<\/svg>|<svg[^/>]*\/\s*>)\s*$/i;

const isSvg = input => Boolean(input) && !isBinary(input) && regex.test(clean(input.toString()).replace(htmlCommentRegex, ''));

module.exports = isSvg;
// TODO: Remove this for the next major release
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -42,6 +42,7 @@
"devDependencies": {
"@types/node": "^11.13.0",
"ava": "^1.4.1",
"time-span": "^4.0.0",
"tsd": "^0.7.2",
"xo": "^0.24.0"
}
Expand Down
13 changes: 13 additions & 0 deletions test.js
@@ -1,5 +1,6 @@
import fs from 'fs';
import test from 'ava';
import timeSpan from 'time-span';
import isSvg from '.';

test('valid SVGs', t => {
Expand Down Expand Up @@ -70,3 +71,15 @@ test('support markup inside Entity tags', t => {
</g>
</svg>`));
});

test('regex should not be quadratic', t => {
const end = timeSpan();

isSvg(`<!doctype svg ${' '.repeat(34560)}`);

if (end.seconds() < 10) {
t.pass();
} else {
t.fail();
}
});

0 comments on commit 01f8a08

Please sign in to comment.