Skip to content

Commit

Permalink
fix(SVG): fix SVG style vulnerability (#36)
Browse files Browse the repository at this point in the history
* fix(SVG): fix SVG style vulnerability

* fix build
  • Loading branch information
waterplea authored Feb 21, 2020
1 parent 207defc commit 87edb38
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 7 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ script:
- npm run lint
- npm run build
- npm run test:ci
- npm run build:demo
16 changes: 16 additions & 0 deletions projects/demo/src/polyfills.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
// IE9, IE10 and IE11 requires all of the following polyfills.
import 'core-js/es6/array';
import 'core-js/es6/date';
import 'core-js/es6/function';
import 'core-js/es6/map';
import 'core-js/es6/math';
import 'core-js/es6/number';
import 'core-js/es6/object';
import 'core-js/es6/parse-float';
import 'core-js/es6/parse-int';
import 'core-js/es6/regexp';
import 'core-js/es6/set';
import 'core-js/es6/string';
import 'core-js/es6/symbol';
import 'core-js/es6/weak-map';

import 'core-js/es6/reflect';
import 'core-js/es7/reflect';

Expand Down
11 changes: 11 additions & 0 deletions projects/ng-dompurify/src/lib/test/ng-dompurify.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {NgDompurifySanitizer} from '../ng-dompurify.service';
import {DOMPURIFY_HOOKS} from '../tokens/dompurify-hooks';
import {SANITIZE_STYLE} from '../tokens/sanitize-style';
import {NgDompurifyHook} from '../types/ng-dompurify-hook';
import {createUponSanitizeElementHook} from '../utils/createUponSanitizeElementHook';
import {cleanHtml, dirtyHtml} from './test-samples/html';
import {sanitizeStyle} from './test-samples/sanitizeStyle';
import {cleanStyleTag, dirtyStyleTag} from './test-samples/style';
Expand Down Expand Up @@ -86,6 +87,16 @@ describe('NgDompurifySanitizer', () => {

expect(sanitized).toBe(`<div>test</div>`);
});

it('clears style when sheet is not available', () => {
const style = document.createElement('STYLE');
const hook = createUponSanitizeElementHook(v => v);

style.textContent = 'hapica';
hook(style, null, {});

expect(style.textContent).toBe('');
});
});

describe('NgDompurifySanitizer default DI', () => {
Expand Down
5 changes: 3 additions & 2 deletions projects/ng-dompurify/src/lib/test/test-samples/html.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export const dirtyHtml = `<p style="color: red; background-image: url('evil')">HELLO<iframe/\/src=JavaScript:alert&lpar;1)></ifrAMe><br>goodbye</p>`;
export const cleanHtml = `<p style="color:red;">HELLO<br>goodbye</p>`;
export const dirtyHtml = `<p style="color: red; background-image: url('evil')">HELLO<iframe/\/src=JavaScript:alert&lpar;1)></ifrAMe><br>goodbye</p><style>*{x:expression(alert(1), color: red)}</style><svg><circle style="x:expression(alert(1))" /></svg>`;
export const cleanHtml = `<p style="color:red;">HELLO<br>goodbye</p><style>*{
}</style><svg><circle></circle></svg>`;
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ export function createAfterSanitizeAttributes(
sanitizeStyle: SanitizeStyle,
): DompurifyHook {
return node => {
if (!(node instanceof HTMLElement) || !node.hasAttribute('style')) {
if (
(!(node instanceof HTMLElement) && !(node instanceof SVGElement)) ||
!node.hasAttribute('style')
) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@ export function createUponSanitizeElementHook(
sanitizeStyle: SanitizeStyle,
): DompurifyHook {
return node => {
if (node instanceof HTMLStyleElement && node.sheet instanceof CSSStyleSheet) {
node.textContent = addCSSRules(node.sheet.cssRules, sanitizeStyle).join('\n');
if (node instanceof HTMLStyleElement || node instanceof SVGStyleElement) {
// /~https://github.com/microsoft/TypeScript/issues/36896
const {sheet} = node as HTMLStyleElement;

if (sheet instanceof CSSStyleSheet) {
node.textContent = addCSSRules(sheet.cssRules, sanitizeStyle).join('\n');
} else {
node.textContent = '';
}
}
};
}
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"importHelpers": true,
"noUnusedLocals": true,
"strict": true,
"target": "es2015",
"target": "es5",
"typeRoots": ["node_modules/@types"],
"lib": ["es2018", "dom"],
"paths": {
Expand Down

0 comments on commit 87edb38

Please sign in to comment.