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
This commit is contained in:
parent
c7f4abf18a
commit
358c50e226
|
@ -19,7 +19,7 @@ import {SecurityContext} from '../core';
|
|||
//
|
||||
// =================================================================================================
|
||||
|
||||
/** Map from tagName|propertyName SecurityContext. Properties applying to all tags use '*'. */
|
||||
/** Map from tagName|propertyName to SecurityContext. Properties applying to all tags use '*'. */
|
||||
let _SECURITY_SCHEMA!: {[k: string]: SecurityContext};
|
||||
|
||||
export function SECURITY_SCHEMA(): {[k: string]: SecurityContext} {
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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();
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue