protected static function compileDirective(string $directive, $policies): string
    {
        // handle special directive first
        switch ($directive) {
            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/plugin-types
            case 'plugin-types':
                return empty($policies) ? '' : sprintf('%s %s', $directive, implode(' ', $policies));

            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/require-sri-for
            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/sandbox
            case 'require-sri-for':
            case 'sandbox':
                return empty($policies) ? '' : sprintf('%s %s', $directive, $policies);
        }

        // when policies is empty, we assume that user disallow this directive
        if (empty($policies)) {
            return sprintf("%s 'none'", $directive);
        }

        $ret = [$directive];

        // keyword source, https://www.w3.org/TR/CSP/#grammardef-keyword-source, https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src
        foreach (['self', 'unsafe-inline', 'unsafe-eval', 'strict-dynamic', 'unsafe-hashed-attributes', 'report-sample'] as $keyword) {
            if (! empty($policies[$keyword])) {
                $ret[] = sprintf("'%s'", $keyword);
            }
        }

        if (! empty($policies['allow'])) {
            foreach ($policies['allow'] as $url) {
                // removes illegal URL characters
                if (false !== ($url = filter_var($url, FILTER_SANITIZE_URL))) {
                    $ret[] = $url;
                }
            }
        }

        if (! empty($policies['hashes'])) {
            foreach ($policies['hashes'] as $algo => $hashes) {
                // skip not support algorithm, https://www.w3.org/TR/CSP/#grammardef-hash-source
                if (! in_array($algo, ['sha256', 'sha384', 'sha512'])) {
                    continue;
                }

                foreach ($hashes as $value) {
                    // skip invalid value
                    if (! self::isBase64Valid($value)) {
                        continue;
                    }

                    $ret[] = sprintf("'%s-%s'", $algo, $value);
                }
            }
        }

        if (! empty($policies['nonces'])) {
            foreach ($policies['nonces'] as $nonce) {
                // skip invalid value, https://www.w3.org/TR/CSP/#grammardef-nonce-source
                if (! self::isBase64Valid($nonce)) {
                    continue;
                }

                $ret[] = sprintf("'nonce-%s'", $nonce);
            }
        }

        if (! empty($policies['schemes'])) {
            foreach ($policies['schemes'] as $scheme) {
                $ret[] = sprintf('%s', $scheme);
            }
        }

        return implode(' ', $ret);
    }
protected static function compileDirective(string $directive, $policies): string
    {
        // handle special directive first
        switch ($directive) {
            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/plugin-types
            case 'plugin-types':
                return empty($policies) ? '' : sprintf('%s %s', $directive, implode(' ', $policies));

            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/require-sri-for
            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/sandbox
            case 'require-sri-for':
            case 'sandbox':
                return empty($policies) ? '' : sprintf('%s %s', $directive, $policies);
        }

        // when policies is empty, we assume that user disallow this directive
        if (empty($policies)) {
            return sprintf("%s 'none'", $directive);
        }

        $ret = [$directive];

        // keyword source, https://www.w3.org/TR/CSP/#grammardef-keyword-source, https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src
        foreach (['self', 'unsafe-inline', 'unsafe-eval', 'strict-dynamic', 'unsafe-hashed-attributes', 'report-sample'] as $keyword) {
            if (! empty($policies[$keyword])) {
                $ret[] = sprintf("'%s'", $keyword);
            }
        }

        if (! empty($policies['allow'])) {
            foreach ($policies['allow'] as $url) {
                // removes illegal URL characters
                if (false !== ($url = filter_var($url, FILTER_SANITIZE_URL))) {
                    $ret[] = $url;
                }
            }
        }

        if (! empty($policies['hashes'])) {
            foreach ($policies['hashes'] as $algo => $hashes) {
                // skip not support algorithm, https://www.w3.org/TR/CSP/#grammardef-hash-source
                if (! in_array($algo, ['sha256', 'sha384', 'sha512'])) {
                    continue;
                }

                foreach ($hashes as $value) {
                    // skip invalid value
                    if (! self::isBase64Valid($value)) {
                        continue;
                    }

                    $ret[] = sprintf("'%s-%s'", $algo, $value);
                }
            }
        }

        if (! empty($policies['nonces'])) {
            foreach ($policies['nonces'] as $nonce) {
                // skip invalid value, https://www.w3.org/TR/CSP/#grammardef-nonce-source
                if (! self::isBase64Valid($nonce)) {
                    continue;
                }

                $ret[] = sprintf("'nonce-%s'", $nonce);
            }
        }

        if (! empty($policies['schemes'])) {
            foreach ($policies['schemes'] as $scheme) {
                $ret[] = sprintf('%s', $scheme);
            }
        }

        return implode(' ', $ret);
    }
protected static function compileDirective ( string $ directive , $ policies ) : string { // handle special directive first switch ( $ directive ) { // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/plugin-types case 'plugin-types' : return empty ( $ policies ) ? '' : sprintf ( '%s %s' , $ directive , implode ( ' ' , $ policies ) ) ; // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/require-sri-for // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/sandbox case 'require-sri-for' : case 'sandbox' : return empty ( $ policies ) ? '' : sprintf ( '%s %s' , $ directive , $ policies ) ; } // when policies is empty, we assume that user disallow this directive if ( empty ( $ policies ) ) { return sprintf ( "%s 'none'" , $ directive ) ; } $ ret = [ $ directive ] ; // keyword source, https://www.w3.org/TR/CSP/#grammardef-keyword-source, https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src foreach ( [ 'self' , 'unsafe-inline' , 'unsafe-eval' , 'strict-dynamic' , 'unsafe-hashed-attributes' , 'report-sample' ] as $ keyword ) { if ( ! empty ( $ policies [ $ keyword ] ) ) { $ ret [ ] = sprintf ( "'%s'" , $ keyword ) ; } } if ( ! empty ( $ policies [ 'allow' ] ) ) { foreach ( $ policies [ 'allow' ] as $ url ) { // removes illegal URL characters if ( false !== ( $ url = filter_var ( $ url , FILTER_SANITIZE_URL ) ) ) { $ ret [ ] = $ url ; } } } if ( ! empty ( $ policies [ 'hashes' ] ) ) { foreach ( $ policies [ 'hashes' ] as $ algo => $ hashes ) { // skip not support algorithm, https://www.w3.org/TR/CSP/#grammardef-hash-source if ( ! in_array ( $ algo , [ 'sha256' , 'sha384' , 'sha512' ] ) ) { continue ; } foreach ( $ hashes as $ value ) { // skip invalid value if ( ! self :: isBase64Valid ( $ value ) ) { continue ; } $ ret [ ] = sprintf ( "'%s-%s'" , $ algo , $ value ) ; } } } if ( ! empty ( $ policies [ 'nonces' ] ) ) { foreach ( $ policies [ 'nonces' ] as $ nonce ) { // skip invalid value, https://www.w3.org/TR/CSP/#grammardef-nonce-source if ( ! self :: isBase64Valid ( $ nonce ) ) { continue ; } $ ret [ ] = sprintf ( "'nonce-%s'" , $ nonce ) ; } } if ( ! empty ( $ policies [ 'schemes' ] ) ) { foreach ( $ policies [ 'schemes' ] as $ scheme ) { $ ret [ ] = sprintf ( '%s' , $ scheme ) ; } } return implode ( ' ' , $ ret ) ; }
Compile a subgroup into a policy string.

@param string $directive
@param mixed $policies

@return string
Compile a subgroup into a policy string .