Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
- Loading branch information
1 parent
c7f4abf
commit 358c50e
Showing
3 changed files
with
82 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/** | ||
* @license | ||
* Copyright Google LLC All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
|
||
/** | ||
* Set of tagName|propertyName corresponding to Trusted Types sinks. Properties applying to all | ||
* tags use '*'. | ||
* | ||
* Extracted from, and should be kept in sync with | ||
* https://w3c.github.io/webappsec-trusted-types/dist/spec/#integrations | ||
*/ | ||
const TRUSTED_TYPES_SINKS = new Set<string>([ | ||
// NOTE: All strings in this set *must* be lowercase! | ||
|
||
// TrustedHTML | ||
'iframe|srcdoc', | ||
'*|innerhtml', | ||
'*|outerhtml', | ||
|
||
// NB: no TrustedScript here, as the corresponding tags are stripped by the compiler. | ||
|
||
// TrustedScriptURL | ||
'embed|src', | ||
'object|codebase', | ||
'object|data', | ||
]); | ||
|
||
/** | ||
* isTrustedTypesSink returns true if the given property on the given DOM tag is a Trusted Types | ||
* sink. In that case, use `ElementSchemaRegistry.securityContext` to determine which particular | ||
* Trusted Type is required for values passed to the sink: | ||
* - SecurityContext.HTML corresponds to TrustedHTML | ||
* - SecurityContext.RESOURCE_URL corresponds to TrustedScriptURL | ||
*/ | ||
export function isTrustedTypesSink(tagName: string, propName: string): boolean { | ||
// Make sure comparisons are case insensitive, so that case differences between attribute and | ||
// property names do not have a security impact. | ||
tagName = tagName.toLowerCase(); | ||
propName = propName.toLowerCase(); | ||
|
||
return TRUSTED_TYPES_SINKS.has(tagName + '|' + propName) || | ||
TRUSTED_TYPES_SINKS.has('*|' + propName); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/** | ||
* @license | ||
* Copyright Google LLC All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
|
||
import {isTrustedTypesSink} from '@angular/compiler/src/schema/trusted_types_sinks'; | ||
import {describe, expect, it} from '@angular/core/testing/src/testing_internal'; | ||
|
||
{ | ||
describe('isTrustedTypesSink', () => { | ||
it('should classify Trusted Types sinks', () => { | ||
expect(isTrustedTypesSink('iframe', 'srcdoc')).toBeTrue(); | ||
expect(isTrustedTypesSink('p', 'innerHTML')).toBeTrue(); | ||
expect(isTrustedTypesSink('embed', 'src')).toBeTrue(); | ||
expect(isTrustedTypesSink('a', 'href')).toBeFalse(); | ||
expect(isTrustedTypesSink('base', 'href')).toBeFalse(); | ||
expect(isTrustedTypesSink('div', 'style')).toBeFalse(); | ||
}); | ||
|
||
it('should classify Trusted Types sinks case insensitive', () => { | ||
expect(isTrustedTypesSink('p', 'iNnErHtMl')).toBeTrue(); | ||
expect(isTrustedTypesSink('p', 'formaction')).toBeFalse(); | ||
expect(isTrustedTypesSink('p', 'formAction')).toBeFalse(); | ||
}); | ||
|
||
it('should classify attributes as Trusted Types sinks', () => { | ||
expect(isTrustedTypesSink('p', 'innerHtml')).toBeTrue(); | ||
expect(isTrustedTypesSink('p', 'formaction')).toBeFalse(); | ||
}); | ||
}); | ||
} |