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
5b4fd22194
commit
26cdc53d9c
4 changed files with 45 additions and 13 deletions
|
|
@ -8278,6 +8278,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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@
|
|||
"EventType2",
|
||||
"GuardsCheckEnd",
|
||||
"GuardsCheckStart",
|
||||
"HREF_RESOURCE_TAGS",
|
||||
"HistoryStateManager",
|
||||
"INITIAL_NAVIGATION",
|
||||
"INITIAL_VALUE",
|
||||
|
|
@ -211,6 +212,7 @@
|
|||
"SIGNAL",
|
||||
"SIGNAL_NODE",
|
||||
"SIMPLE_CHANGES_STORE",
|
||||
"SRC_RESOURCE_TAGS",
|
||||
"SafeSubscriber",
|
||||
"SafeValueImpl",
|
||||
"Sanitizer",
|
||||
|
|
@ -748,4 +750,4 @@
|
|||
"ɵɵsanitizeUrl",
|
||||
"ɵɵtext",
|
||||
"ɵɵtextInterpolate1"
|
||||
]
|
||||
]
|
||||
Loading…
Reference in a new issue