Skip to content

Commit 7a668cd

Browse files
fix($sanitize): blacklist SVG <use> elements
The use element can reference external svg's (same origin) and can include xlink javascript urls or foreign object that can execute xss. This change disallows `<use>` elements in sanitized SVG markup. An example of a malicious SVG document would be: SVG to sanitize: ``` <svg><use xlink:href="test.svg#xss" /></svg> ``` External SVG file (test.svg) ``` <?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="100" height="100" id="xss"> <a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="javascript:alert(1)"> <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" /> </a> </svg> ``` Here the SVG to sanitize loads in the `test.svg` file via the `<use>` element. The sanitizer is not able to parse this file, which contains malicious executable mark-up. This can only be taken advantage of if the external file is available via the same origin restrictions in place. Closes angular#13453 BREAKING CHANGE: The `<use>` element is now removed from SVG passed to the `$sanitize` service. This element is only used to import external SVG resources, which is a security risk as the `$sanitize` service does not have access to the resource in order to sanitize it.
1 parent 5a674f3 commit 7a668cd

File tree

2 files changed

+8
-1
lines changed

2 files changed

+8
-1
lines changed

src/ngSanitize/sanitize.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ var inlineElements = angular.extend({}, optionalEndTagInlineElements, toMap("a,a
242242
// They can potentially allow for arbitrary javascript to be executed. See #11290
243243
var svgElements = toMap("circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph," +
244244
"hkern,image,linearGradient,line,marker,metadata,missing-glyph,mpath,path,polygon,polyline," +
245-
"radialGradient,rect,stop,svg,switch,text,title,tspan,use");
245+
"radialGradient,rect,stop,svg,switch,text,title,tspan");
246246

247247
// Blocked Elements (will be stripped)
248248
var blockedElements = toMap("script,style");

test/ngSanitize/sanitizeSpec.js

+7
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,13 @@ describe('HTML', function() {
292292
'<svg xmlns="http://www.w3.org/2000/svg"><a xlink:href="?" xmlns:xlink="http://www.w3.org/1999/xlink"><circle r="400"></circle></a></svg>',
293293
'<svg xmlns="http://www.w3.org/2000/svg"><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="?"><circle r="400"></circle></a></svg>');
294294
});
295+
296+
it('should not accept SVG `use` tags', function() {
297+
expectHTML('<svg><use xlink:href="test.svg#xss" /></svg>')
298+
.toBeOneOf('<svg></svg>',
299+
'<svg xmlns:xlink="http://www.w3.org/1999/xlink"></svg>',
300+
'<svg xmlns="http://www.w3.org/2000/svg"></svg>');
301+
});
295302
});
296303

297304

0 commit comments

Comments
 (0)