feat(core): create internal Trusted Types module (#39207)
Add a module that provides a Trusted Types policy for use internally by Angular. The policy is created lazily and stored in a module-local variable. For now the module does not allow configuring custom policies or policy names, and instead creates its own policy with 'angular' as a fixed policy name. This is to more easily support tree-shakability. Helper functions for unsafely converting strings to each of the three Trusted Types are also introduced, with documentation that make it clear that their use requires a security review. When Trusted Types are not available, these helper functions fall back to returning strings. PR Close #39207
This commit is contained in:
parent
c4266fb729
commit
0875fd2360
|
@ -0,0 +1,87 @@
|
|||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview
|
||||
* A module to facilitate use of a Trusted Types policy internally within
|
||||
* Angular. It lazily constructs the Trusted Types policy, providing helper
|
||||
* utilities for promoting strings to Trusted Types. When Trusted Types are not
|
||||
* available, strings are used as a fallback.
|
||||
* @security All use of this module is security-sensitive and should go through
|
||||
* security review.
|
||||
*/
|
||||
|
||||
import {global} from '../global';
|
||||
|
||||
/**
|
||||
* The Trusted Types policy, or null if Trusted Types are not
|
||||
* enabled/supported, or undefined if the policy has not been created yet.
|
||||
*/
|
||||
let policy: TrustedTypePolicy|null|undefined;
|
||||
|
||||
/**
|
||||
* Returns the Trusted Types policy, or null if Trusted Types are not
|
||||
* enabled/supported. The first call to this function will create the policy.
|
||||
*/
|
||||
function getPolicy(): TrustedTypePolicy|null {
|
||||
if (policy === undefined) {
|
||||
policy = null;
|
||||
if (global.trustedTypes) {
|
||||
try {
|
||||
policy = (global.trustedTypes as TrustedTypePolicyFactory).createPolicy('angular', {
|
||||
createHTML: (s: string) => s,
|
||||
createScript: (s: string) => s,
|
||||
createScriptURL: (s: string) => s,
|
||||
});
|
||||
} catch {
|
||||
// trustedTypes.createPolicy throws if called with a name that is
|
||||
// already registered, even in report-only mode. Until the API changes,
|
||||
// catch the error not to break the applications functionally. In such
|
||||
// cases, the code will fall back to using strings.
|
||||
}
|
||||
}
|
||||
}
|
||||
return policy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsafely promote a string to a TrustedHTML, falling back to strings when
|
||||
* Trusted Types are not available.
|
||||
* @security This is a security-sensitive function; any use of this function
|
||||
* must go through security review. In particular, it must be assured that the
|
||||
* provided string will never cause an XSS vulnerability if used in a context
|
||||
* that will be interpreted as HTML by a browser, e.g. when assigning to
|
||||
* element.innerHTML.
|
||||
*/
|
||||
export function trustedHTMLFromString(html: string): TrustedHTML|string {
|
||||
return getPolicy()?.createHTML(html) || html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsafely promote a string to a TrustedScript, falling back to strings when
|
||||
* Trusted Types are not available.
|
||||
* @security In particular, it must be assured that the provided string will
|
||||
* never cause an XSS vulnerability if used in a context that will be
|
||||
* interpreted and executed as a script by a browser, e.g. when calling eval.
|
||||
*/
|
||||
export function trustedScriptFromString(script: string): TrustedScript|string {
|
||||
return getPolicy()?.createScript(script) || script;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsafely promote a string to a TrustedScriptURL, falling back to strings
|
||||
* when Trusted Types are not available.
|
||||
* @security This is a security-sensitive function; any use of this function
|
||||
* must go through security review. In particular, it must be assured that the
|
||||
* provided string will never cause an XSS vulnerability if used in a context
|
||||
* that will cause a browser to load and execute a resource, e.g. when
|
||||
* assigning to script.src.
|
||||
*/
|
||||
export function trustedScriptURLFromString(url: string): TrustedScriptURL|string {
|
||||
return getPolicy()?.createScriptURL(url) || url;
|
||||
}
|
Loading…
Reference in New Issue