mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
fix(core): sanitize sensitive attributes on SVG script elements
This commit updates the DOM security schema and sanitization logic to properly recognize and sanitize `href` and `xlink:href` attributes on SVG `<script>` elements.
This commit is contained in:
parent
4755bbd949
commit
c2c2b4aaa8
4 changed files with 44 additions and 12 deletions
|
|
@ -8530,6 +8530,34 @@ runInEachFileSystem((os: string) => {
|
|||
expect(trim(jsContents)).toContain(trim(hostBindingsFn));
|
||||
});
|
||||
|
||||
it('should generate sanitizers for URL properties in SVG script fn in Component', () => {
|
||||
env.write(
|
||||
'test.ts',
|
||||
`
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'test-cmp',
|
||||
template: \`
|
||||
<svg>
|
||||
<script [attr.xlink:href]="attr" [attr.href]="attr"></script>
|
||||
</svg>
|
||||
\`,
|
||||
})
|
||||
export class TestCmp {
|
||||
attr = './script.js';
|
||||
}
|
||||
`,
|
||||
);
|
||||
|
||||
env.driveMain();
|
||||
|
||||
const jsContents = env.getContents('test.js');
|
||||
expect(jsContents).toContain(
|
||||
'i0.ɵɵattribute("href", ctx.attr, i0.ɵɵsanitizeResourceUrl, "xlink")("href", ctx.attr, i0.ɵɵsanitizeResourceUrl);',
|
||||
);
|
||||
});
|
||||
|
||||
it('should not generate sanitizers for URL properties in hostBindings fn in Component', () => {
|
||||
env.write(
|
||||
`test.ts`,
|
||||
|
|
|
|||
|
|
@ -134,6 +134,10 @@ export function SECURITY_SCHEMA(): {[k: string]: SecurityContext} {
|
|||
'object|codebase',
|
||||
'object|data',
|
||||
'script|src',
|
||||
// The below two are for Script SVG
|
||||
// See: https://developer.mozilla.org/en-US/docs/Web/API/SVGScriptElement/href
|
||||
'script|href',
|
||||
'script|xlink:href',
|
||||
]);
|
||||
|
||||
// Keep this in sync with SECURITY_SENSITIVE_ELEMENTS in packages/core/src/sanitization/sanitization.ts
|
||||
|
|
|
|||
|
|
@ -213,6 +213,10 @@ export function ɵɵtrustConstantResourceUrl(url: TemplateStringsArray): Trusted
|
|||
return trustedScriptURLFromString(url[0]);
|
||||
}
|
||||
|
||||
// Define sets outside the function for O(1) lookups and memory efficiency
|
||||
const SRC_RESOURCE_TAGS = new Set(['embed', 'frame', 'iframe', 'media', 'script']);
|
||||
const HREF_RESOURCE_TAGS = new Set(['base', 'link', 'script']);
|
||||
|
||||
/**
|
||||
* Detects which sanitizer to use for URL property, based on tag name and prop name.
|
||||
*
|
||||
|
|
@ -221,18 +225,12 @@ export function ɵɵtrustConstantResourceUrl(url: TemplateStringsArray): Trusted
|
|||
* If tag and prop names don't match Resource URL schema, use URL sanitizer.
|
||||
*/
|
||||
export function getUrlSanitizer(tag: string, prop: string) {
|
||||
if (
|
||||
(prop === 'src' &&
|
||||
(tag === 'embed' ||
|
||||
tag === 'frame' ||
|
||||
tag === 'iframe' ||
|
||||
tag === 'media' ||
|
||||
tag === 'script')) ||
|
||||
(prop === 'href' && (tag === 'base' || tag === 'link'))
|
||||
) {
|
||||
return ɵɵsanitizeResourceUrl;
|
||||
}
|
||||
return ɵɵsanitizeUrl;
|
||||
const isResource =
|
||||
(prop === 'src' && SRC_RESOURCE_TAGS.has(tag)) ||
|
||||
(prop === 'href' && HREF_RESOURCE_TAGS.has(tag)) ||
|
||||
(prop === 'xlink:href' && tag === 'script');
|
||||
|
||||
return isResource ? ɵɵsanitizeResourceUrl : ɵɵsanitizeUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@
|
|||
"HOST",
|
||||
"HOST_ATTR",
|
||||
"HOST_TAG_NAME",
|
||||
"HREF_RESOURCE_TAGS",
|
||||
"HYDRATION",
|
||||
"HistoryStateManager",
|
||||
"HostAttributeToken",
|
||||
|
|
@ -274,6 +275,7 @@
|
|||
"SIGNAL",
|
||||
"SIGNAL_NODE",
|
||||
"SIMPLE_CHANGES_STORE",
|
||||
"SRC_RESOURCE_TAGS",
|
||||
"SVG_NAMESPACE",
|
||||
"SafeSubscriber",
|
||||
"SafeValueImpl",
|
||||
|
|
|
|||
Loading…
Reference in a new issue