fileoverview author lwe google license import * as csp from '../csp' ; import { Csp , Keyword } from '../csp' ; import { Finding , Severity , Type } from '../finding' ; param parsedCsp export function checkStrictDynamic ( parsedCsp ) { const directiveName = parsedCsp . getEffectiveDirective ( csp . Directive . SCRIPT_SRC ) ; const values = parsedCsp . directives [ directiveName ] || [ ] ; const schemeOrHostPresent = values . some ( ( v ) => ! v . startsWith ( '\'' ) ) ; if ( schemeOrHostPresent && ! values . includes ( Keyword . STRICT_DYNAMIC ) ) { return [ new Finding ( Type . STRICT_DYNAMIC , 'Host allowlists can frequently be bypassed. Consider using ' + '\'strict-dynamic\' in combination with CSP nonces or hashes.' , Severity . STRICT_CSP , directiveName ) ] ; } return [ ] ; } param parsedCsp export function checkStrictDynamicNotStandalone ( parsedCsp ) { const directiveName = parsedCsp . getEffectiveDirective ( csp . Directive . SCRIPT_SRC ) ; const values = parsedCsp . directives [ directiveName ] || [ ] ; if ( values . includes ( Keyword . STRICT_DYNAMIC ) && ( ! parsedCsp . policyHasScriptNonces ( ) && ! parsedCsp . policyHasScriptHashes ( ) ) ) { return [ new Finding ( Type . STRICT_DYNAMIC_NOT_STANDALONE , '\'strict-dynamic\' without a CSP nonce/hash will block all scripts.' , Severity . INFO , directiveName ) ] ; } return [ ] ; } param parsedCsp export function checkUnsafeInlineFallback ( parsedCsp ) { if ( ! parsedCsp . policyHasScriptNonces ( ) && ! parsedCsp . policyHasScriptHashes ( ) ) { return [ ] ; } const directiveName = parsedCsp . getEffectiveDirective ( csp . Directive . SCRIPT_SRC ) ; const values = parsedCsp . directives [ directiveName ] || [ ] ; if ( ! values . includes ( Keyword . UNSAFE_INLINE ) ) { return [ new Finding ( Type . UNSAFE_INLINE_FALLBACK , 'Consider adding \'unsafe-inline\' (ignored by browsers supporting ' + 'nonces/hashes) to be backward compatible with older browsers.' , Severity . STRICT_CSP , directiveName ) ] ; } return [ ] ; } param parsedCsp export function checkAllowlistFallback ( parsedCsp ) { const directiveName = parsedCsp . getEffectiveDirective ( csp . Directive . SCRIPT_SRC ) ; const values = parsedCsp . directives [ directiveName ] || [ ] ; if ( ! values . includes ( Keyword . STRICT_DYNAMIC ) ) { return [ ] ; } if ( ! values . some ( ( v ) => [ 'http:' , 'https:' , '*' ] . includes ( v ) || v . includes ( '.' ) ) ) { return [ new Finding ( Type . ALLOWLIST_FALLBACK , 'Consider adding https: and http: url schemes (ignored by browsers ' + 'supporting \'strict-dynamic\') to be backward compatible with older ' + 'browsers.' , Severity . STRICT_CSP , directiveName ) ] ; } return [ ] ; } param parsedCsp export function checkRequiresTrustedTypesForScripts ( parsedCsp ) { const directiveName = parsedCsp . getEffectiveDirective ( csp . Directive . REQUIRE_TRUSTED_TYPES_FOR ) ; const values = parsedCsp . directives [ directiveName ] || [ ] ; if ( ! values . includes ( csp . TrustedTypesSink . SCRIPT ) ) { return [ new Finding ( Type . REQUIRE_TRUSTED_TYPES_FOR_SCRIPTS , 'Consider requiring Trusted Types for scripts to lock down DOM XSS ' + 'injection sinks. You can do this by adding ' + '"require-trusted-types-for \'script\'" to your policy.' , Severity . INFO , csp . Directive . REQUIRE_TRUSTED_TYPES_FOR ) ] ; } return [ ] ; }