[wp-trac] [WordPress Trac] #39941: Allow using Content-Security-Policy without unsafe-inline
WordPress Trac
noreply at wordpress.org
Sun Aug 10 22:44:51 UTC 2025
#39941: Allow using Content-Security-Policy without unsafe-inline
-------------------------------------------------+-------------------------
Reporter: tomdxw | Owner:
| adamsilverstein
Type: enhancement | Status: closed
Priority: normal | Milestone: 5.7
Component: Security | Version: 4.8
Severity: normal | Resolution: fixed
Keywords: has-patch has-unit-tests commit | Focuses: javascript
has-dev-note |
-------------------------------------------------+-------------------------
Comment (by amanandhishoe):
Sadly many still print scripts directly into the html. If they all used
calls like wp_add_inline_script() making a robust CSP would be simple.
In my CSP generator, I'm having to exam inline scripts to see which ones
to generate hashes for:
{{{
// Allow: your tagged inlines, Rocket placeholders/loader, Rocket IE
snippet.
$tok = preg_quote( DBTN_CSP_TOKEN, '#' );
$is_ours = preg_match( '#\bdata-owner=["\']dbtn["\']#i', $attrs )
&& preg_match( '#\bdata-cspid=["\']' .
$tok . '["\']#i', $attrs );
$is_rocket_lazy = stripos( $attrs, 'rocketlazyloadscript' ) !== false;
$is_rocket_loader = stripos( $body, 'RocketLazyLoadScripts' ) !== false;
$is_rocket_ie = strpos( $body, 'nowprocket=1' ) !== false
&& strpos( $body,
'navigator.userAgent.match(/MSIE' ) !== false;
$sitekey = 'myturnstilesitekey'; // your prod key
$looks_like_turnstile = (
// uses Turnstile API
preg_match('#\bturnstile\.(?:render|remove)\s*\(#', $body)
// targets your known element
&& strpos($body, 'cf-turnstile-woo-checkout') !== false
// carries your exact sitekey
&& preg_match('#"sitekey"\s*:\s*"' . preg_quote($sitekey, '#') .
'"#', $body)
// no obviously dangerous tokens
&&
!preg_match('#\b(?:eval|Function|innerHTML\s*=|document\.write)\b#',
$body)
);
if ( ! ( $is_ours || $is_rocket_lazy || $is_rocket_loader || $is_rocket_ie
|| $looks_like_turnstile ) ) {
continue;
}
$hashes_a[] = "'sha256-" . base64_encode( hash( 'sha256', $body, true ) )
. "'";
}}}
Originally I was generating hashes for all inline scripts, but am now only
making hashes for scripts I know are good. It's easy to filter those which
are created with routines like wp_add_inline_script, but there are plugins
and themes that print inline scripts directly into the html.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/39941#comment:126>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list