这是indexloc提供的服务,不要输入任何密码
Skip to content

Detect script tags that load or contain JavaScript to prevent strict CSP-compatibility backsliding. #1956

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

enricocarraro
Copy link

@enricocarraro enricocarraro commented Oct 23, 2020

From WP trac ticket #51407:

Content Security Policy is a mechanism designed to make applications more secure against common web vulnerabilities, particularly cross-site scripting. It is enabled by setting the Content-Security-Policy HTTP response header.
An application can add a critical defense-in-depth layer against markup injection attacks by adopting a strict policy that prevents the loading of untrusted scripts or plugins.
A basic policy (nonce + strict-dynamic + unsafe-eval) would block more than 40% of the XSS sinks.

To make an application compatible with strict CSP, it is necessary to make changes to HTML templates and client-side code and add the policy header:

  • Add nonces to <script> elements
  • Refactor inline event handlers and javascript: URIs
  • Refactor calls to JS APIs incompatible with CSP
  • Serve the Content-Security-Policy header

More on CSP.

A series of efforts have been made to enable strict-CSP compatibility in WordPress, the most important being assuring each trusted script tag can be injected with a nonce (WP PR 498, and WP PR 551).

This sniff should prevent developers from writing strict-CSP incompatible code, at least for what concerns script tags. It detects script tags that should be either enqueued or generated by the new script templating functions (WP PR 591) that will be introduced in WordPress 5.7.

Script loaders standard behaviour:

  • When wp_enqueue_script() is defined: use wp_enqueue_script();
  • otherwise: use wp_get_script_tag() or print directly the tag with wp_print_script_tag().

Inline scripts standard behaviour:

  • When the inline script is associated with an enqueued script and wp_add_inline_script() is defined: use wp_add_inline_script();
  • otherwise: use wp_get_inline_script_tag() or print directly the tag with wp_print_inline_script_tag().

Checklist:

  • Add unit tests.
  • Add XML documentation for the sniff to the WordPress/Docs directory.
  • The build needs to pass.

@enricocarraro enricocarraro force-pushed the wp_get_script_tag branch 2 times, most recently from 1f3640a to c6e62ce Compare October 23, 2020 15:31
…ed by the new script templating functions: wp_get_script_tag() and wp_get_inline_script_tag().
@jrfnl
Copy link
Member

jrfnl commented Oct 23, 2020

Hi @enricocarraro, welcome to this repo! Thanks for the PR.

Checklist of things to do before this PR will be properly reviewed:

  • Add unit tests.
    Please make sure they also contain good code samples testing against false positives and false negatives.
  • Add XML documentation for the sniff to the WordPress/Docs directory.
  • The build needs to pass.

Please feel free to ask for as much guidance as you need from me and the others in the team.

In my case, my remarks will often presume you know what you're doing with PHPCS (as why would you send in a sniff otherwise?), please don't let that intimidate you and ask for as much clarification as you need.


I've had a quick look at it so far and to me it's unclear what this sniff is looking for based on the PR description, so I can't review the code to see if the sniff actually does what it is supposed to do.

Aside from that, the PR description refers to a function which won't be introduced in WP until version 5.7. That implies that the sniff will need to support the $minimum_supported_version property, as WPCS is used by both Core, as well as plugins and themes which often support multiple WP versions.

Other notes:

  • The (complex) regex should probably be a class constant and should be properly documented.
  • Is WP the right category for this sniff or should this sniff be in the Security category ? I honestly don't know at the moment, but would like to see this discussed.
  • We're not a fan of duplicate code and most of this sniff seems to be copied from another sniff.
    1. Should this check be added to that other sniff instead ?
    2. If not, should (part of) the duplicate code be abstracted out ?
  • The sniff has now been added to Extra. As the description mentions fixing this in WP Core, should the sniff be part of the Core ruleset ?

@jrfnl
Copy link
Member

jrfnl commented Oct 23, 2020

Oh and from looking at the PRs for Core, we will need to verify if there are any other sniffs looking at the content of inline scripts and see if these need adjusting to allow for this new way of adding inline scripts, as looking for the <script> tag will no longer work.

Copy link

@vrana vrana left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add some tests?

@enricocarraro
Copy link
Author

enricocarraro commented Oct 27, 2020

Hi @jrfnl, thanks for taking the time to look into this PR and pointing out what is not clear about it.

I've had a quick look at it so far and to me it's unclear what this sniff is looking for based on the PR description, so I can't review the code to see if the sniff actually does what it is supposed to do.

The sniff is looking for script tags that contain inline JavaScript, since the EnqueuedResources sniff only looks for script loaders tags (script tags with the src attribute).

  • Is WP the right category for this sniff or should this sniff be in the Security category ? I honestly don't know at the moment, but would like to see this discussed.

I am not sure what the most appropriate category would be; I placed it into WP since, as you mentioned, TemplatedScripts is similar to EnqueuedResources. In WordPress 5.7 enqueued scripts will be printed using the new functions that enable strict CSP-compatibility.

Aside from that, the PR description refers to a function which won't be introduced in WP until version 5.7. That implies that the sniff will need to support the $minimum_supported_version property, as WPCS is used by both Core, as well as plugins and themes which often support multiple WP versions.

I will make sure to include the property in the next commits.

  1. Should this check be added to that other sniff instead ?

In retrospect, I think it would be better to add this new sniff under EnqueuedResourcesSniff, if there is a way to attach the $minimum_supported_version property only to script tags checks.

The sniff has now been added to Extra. As the description mentions fixing this in WP Core, should the sniff be part of the Core ruleset ?

In my opinion, both NonEnqueuedScript and NonTemplatedInlineScript should be moved to the Core ruleset to prevent strict CSP-compatibility backsliding effectively starting from WordPress 5.7.

@enricocarraro
Copy link
Author

enricocarraro commented Oct 27, 2020

Oh and from looking at the PRs for Core, we will need to verify if there are any other sniffs looking at the content of inline scripts and see if these need adjusting to allow for this new way of adding inline scripts, as looking for the <script> tag will no longer work.

Good point, @jrfnl !
I think looking for new the functions' names (wp_get_script_tag and wp_print_script_tag) should do the job.

@jrfnl
Copy link
Member

jrfnl commented Dec 2, 2022

While it would be nice to have a sniff for this, the PR as-is is not mergable as there are open questions and the sniff isn't accompanied by tests. No action has been taken on this in over two years, so I'm going to close this PR.

@jrfnl jrfnl closed this Dec 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants