[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