Skip to content

Commit 358c50e

Browse files
bjarklerAndrewKushnir
authored andcommittedNov 23, 2020
feat(compiler): add schema for Trusted Types sinks (#39554)
Create a schema with an associated function to classify Trusted Types sinks. Piggyback a typo fix. PR Close #39554
1 parent c7f4abf commit 358c50e

File tree

3 files changed

+82
-1
lines changed

3 files changed

+82
-1
lines changed
 

‎packages/compiler/src/schema/dom_security_schema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {SecurityContext} from '../core';
1919
//
2020
// =================================================================================================
2121

22-
/** Map from tagName|propertyName SecurityContext. Properties applying to all tags use '*'. */
22+
/** Map from tagName|propertyName to SecurityContext. Properties applying to all tags use '*'. */
2323
let _SECURITY_SCHEMA!: {[k: string]: SecurityContext};
2424

2525
export function SECURITY_SCHEMA(): {[k: string]: SecurityContext} {
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
/**
10+
* Set of tagName|propertyName corresponding to Trusted Types sinks. Properties applying to all
11+
* tags use '*'.
12+
*
13+
* Extracted from, and should be kept in sync with
14+
* https://w3c.github.io/webappsec-trusted-types/dist/spec/#integrations
15+
*/
16+
const TRUSTED_TYPES_SINKS = new Set<string>([
17+
// NOTE: All strings in this set *must* be lowercase!
18+
19+
// TrustedHTML
20+
'iframe|srcdoc',
21+
'*|innerhtml',
22+
'*|outerhtml',
23+
24+
// NB: no TrustedScript here, as the corresponding tags are stripped by the compiler.
25+
26+
// TrustedScriptURL
27+
'embed|src',
28+
'object|codebase',
29+
'object|data',
30+
]);
31+
32+
/**
33+
* isTrustedTypesSink returns true if the given property on the given DOM tag is a Trusted Types
34+
* sink. In that case, use `ElementSchemaRegistry.securityContext` to determine which particular
35+
* Trusted Type is required for values passed to the sink:
36+
* - SecurityContext.HTML corresponds to TrustedHTML
37+
* - SecurityContext.RESOURCE_URL corresponds to TrustedScriptURL
38+
*/
39+
export function isTrustedTypesSink(tagName: string, propName: string): boolean {
40+
// Make sure comparisons are case insensitive, so that case differences between attribute and
41+
// property names do not have a security impact.
42+
tagName = tagName.toLowerCase();
43+
propName = propName.toLowerCase();
44+
45+
return TRUSTED_TYPES_SINKS.has(tagName + '|' + propName) ||
46+
TRUSTED_TYPES_SINKS.has('*|' + propName);
47+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {isTrustedTypesSink} from '@angular/compiler/src/schema/trusted_types_sinks';
10+
import {describe, expect, it} from '@angular/core/testing/src/testing_internal';
11+
12+
{
13+
describe('isTrustedTypesSink', () => {
14+
it('should classify Trusted Types sinks', () => {
15+
expect(isTrustedTypesSink('iframe', 'srcdoc')).toBeTrue();
16+
expect(isTrustedTypesSink('p', 'innerHTML')).toBeTrue();
17+
expect(isTrustedTypesSink('embed', 'src')).toBeTrue();
18+
expect(isTrustedTypesSink('a', 'href')).toBeFalse();
19+
expect(isTrustedTypesSink('base', 'href')).toBeFalse();
20+
expect(isTrustedTypesSink('div', 'style')).toBeFalse();
21+
});
22+
23+
it('should classify Trusted Types sinks case insensitive', () => {
24+
expect(isTrustedTypesSink('p', 'iNnErHtMl')).toBeTrue();
25+
expect(isTrustedTypesSink('p', 'formaction')).toBeFalse();
26+
expect(isTrustedTypesSink('p', 'formAction')).toBeFalse();
27+
});
28+
29+
it('should classify attributes as Trusted Types sinks', () => {
30+
expect(isTrustedTypesSink('p', 'innerHtml')).toBeTrue();
31+
expect(isTrustedTypesSink('p', 'formaction')).toBeFalse();
32+
});
33+
});
34+
}

0 commit comments

Comments
 (0)
Please sign in to comment.