Make WordPress Core

Opened 5 months ago

Closed 9 days ago

#64683 closed enhancement (fixed)

_print_scripts should use the wp_inline_script_attributes filter

Reported by: galaxor Owned by: westonruter
Priority: normal Milestone: 7.1
Component: Script Loader Version: 2.8
Severity: normal Keywords: has-patch has-unit-tests commit
Cc: Focuses: javascript

Description (last modified by sabernhardt)

On my site, we want to use a content-security-policy. And in this policy, we would like to not include support for 'unsafe-inline' scripts.

We can include inline scripts, as long as they have a nonce in them. That is, instead of just a <script> tag, if they included a <script nonce="xxxxxxx">, where the nonce is generated on every page load, and if our Content-Security-Policy contains script-src 'nonce-xxxxxxxx'.

Some of the scripts generated by WordPress core—and, indeed, by plugins—print themselves out using the wp_get_inline_script_tag function. When a script does that, then our theme can add a filter on the wp_inline_script_attributes hook, which adds the nonce according to our own logic.

However, there are some inline scripts printed by WordPress core that do not use wp_get_inline_script_tag, and with these scripts, there is no way to for our theme to add a nonce to the script tag, and therefore no way to allow these scripts to run in the context of a Content-Security-Policy that does not allow 'unsafe-inline' scripts.

The scripts added by WordPress core are at least those that are added by wp_default_scripts. Ultimately, these are printed out using the function _print_scripts, in wp-includes/script-loader.php. It prints the script tag using

echo "\n<script{$type_attr}>\n";

where $type_attr is either the empty string or "type='text/javascript'".

I propose that _print_scripts be changed so that instead of echoing the script directly, it constructs the code it wants to output, and prints it onto the page using wp_get_inline_script_tag, so that themes or plugins can add filters on the wp_inline_script_attributes hook to add a nonce (or do anything else).

Is that a good approach? If so, I can submit a pull request.

If there's another approach that would be better, I could do that. Perhaps we want to have a different hook here for some reason.

Change History (9)

#1 @sabernhardt
3 months ago

  • Component GeneralScript Loader
  • Description modified (diff)

Related: #58664

#2 @westonruter
3 months ago

  • Focuses javascript added
  • Milestone Awaiting Review7.1
  • Owner set to westonruter
  • Status newaccepted
  • Version 6.9.12.8

#3 @westonruter
3 months ago

  • Owner changed from westonruter to galaxor
  • Status acceptedassigned

@galaxor Sorry for the delay. Yes, it would be great if _print_scripts() was updated to use wp_print_inline_script_tag() and wp_print_script_tag() instead of manually constructing the script tags. Please do open a PR.

#4 @westonruter
3 months ago

Note that in #57548 we may discontinue script concatenation. But using the correct functions for printing scripts should be done here, and throughout the admin.

For related tickets to enable CSP in the admin: #59446 and #51407.

This ticket was mentioned in PR #11702 on WordPress/wordpress-develop by @sukhendu2002.


3 months ago
#5

  • Keywords has-patch has-unit-tests added

@westonruter commented on PR #11702:


3 months ago
#6

I'll pick this up for 7.1 when trunk is unfrozen.

#7 @westonruter
3 months ago

  • Keywords commit added
  • Owner changed from galaxor to westonruter
  • Status assignedreviewing

#8 @wildworks
12 days ago

Since trunk is no longer frozen, if we are ready to prepare your PR, I would appreciate it if you could commit it by next week's 7.1 Beta1.

#9 @westonruter
9 days ago

  • Resolutionfixed
  • Status reviewingclosed

In 62723:

Script Loader: Enable attribute filters for concatenated scripts.

Replace the manually constructed <script> markup in _print_scripts() with wp_print_inline_script_tag() and wp_print_script_tag(). The merged inline script holding the concatenated wp_localize_script() data, and the load-scripts.php tag itself, are now passed through the wp_inline_script_attributes and wp_script_attributes filters, as every other script tag in core already is. Themes and plugins can therefore add attributes to them, such as the nonce needed to serve the admin under a Content-Security-Policy that disallows unsafe-inline.

The emitted markup is otherwise unchanged, aside from the attribute quoting and entity encoding applied by WP_HTML_Tag_Processor.

Developed in https://github.com/WordPress/wordpress-develop/pull/11702.
Follow-up to r56687, r60719.

Props sukhendu2002, galaxor, wildworks, westonruter.
See #51407, #57548, #58664, #59446.
Fixes #64683.

Note: See TracTickets for help on using tickets.