Page MenuHomePhabricator

CSP: Unlock loading data and block loading scripts for execution
Open, In Progress, MediumPublic

Description

Currently, the CSP is missing a connect-src directive and several other important directives while restricting many data sources. As a result, the CSP is both overcomplicated and less secure than it could be. I think enough time has passed to try and do it in a more structured way. Sorry if this is already planned elsewhere, I'm not aware of any efforts to identify and remove scripts using eval() and similar.

DirectiveWhat it controlsNotes
connect-srcfetch, XHR, WebSocket, etc.Should be relatively permissive; gadgets should be able to download data to enhance editing etc. A starting value could even be *.
script-srcloading and executing JSShould be very restrictive. It should eventually be replaced by the more specific script-src-elem and script-src-attr directives.
script-src-elemloading and executing JS in script tagsCan replace script-src. It should eventually allow only trusted sources and should not include 'unsafe-inline' or 'unsafe-eval'.
script-src-attrevent attributes (e.g. onclick)Can replace script-src. It should eventually be set to 'none' (disabling event handlers in attributes while still allowing using addEventListener() etc).
style-srcloading and processing stylesheetsShould be fairly restrictive. Gadgets may still need to load fonts or external stylesheets, so the current value may be kept.

Other things to consider (if not already considered):

  • font-src *; (or more restrictive)
  • image-src *; (or more restrictive)
  • frame-src 'self'; (or more restrictive)
  • X-Frame-Options: SAMEORIGIN or frame-ancestors 'self'

The rollout could proceed in the following stages.

Stage 1

Start with something like:

  • connect-src *
  • script-src-attr 'unsafe-inline'
  • script-src-elem *current value*
  • img-src * data:
  • probably keep other rules (default-src, object-src, reporting)

In reporting rule, add checks for:

  • script-src-attr: unsafe-inline.
  • script-src-elem: unsafe-eval and unsafe-inline.

Stage 2

After gathering enough initial data, start discussing changes with the teams that add these patterns in core and extensions. Also discuss data with volunteer developers to update gadgets and possibly other tools.

Repeat when new data arrives. Perhaps monthly reviews.

End when no new data is reported and at least a few months have passed.

Stage 3

Remove execution gates when changes are deployed:

  • script-src-attr: unsafe-inline.
  • script-src-elem: unsafe-eval and unsafe-inline.

My guesstimate would be that unsafe-eval will be the easiest to eradicate. This is something old scripts might use, and it should be fairly easy to fix. In the wider JS ecosystem, eval is something that older libraries used, but I think most of them are not used on Wikimedia sites.

CSP rules graph

CSP rules have fallbacks, below graph should contain most of them. I think the image is from 2023, but nothing important for wikis was added recently. I mean I assume Trusted Types would be too complicated for wikis (not feasible).

image.png (1,012×368 px, 45 KB)

Event Timeline

Previously somewhat discussed in T419265

I'd just point out that there are a lot of different objectives you can try and accomplish (e.g. prevent different types of xss vs prevent user scripts from sending private data to third parties). I think there is a lot of confusion caused by people not being clear on what they are trying to accomplish

I assume the security team wanted to prevent executing remote code. The way to do that without blocking requests for data is first try to get rid of ways to execute downloaded data as code. So that would mean getting rid of unsafe-eval and unsafe-inline. But my assumptions might not be correct.

sbassett changed the task status from Open to In Progress.Jul 13 2026, 4:27 PM
sbassett claimed this task.
sbassett triaged this task as Medium priority.
sbassett moved this task from Incoming to In Progress on the Security-Team board.

Thanks for filing this. There are several similar tasks under the ContentSecurityPolicy project, namely T239077, T327588 and T245424. But I think those can maybe be rolled into this task. The next step here, IMO, would be to add the more restrictive directives here to a report-only policy that builds off of the current enforcing CSP in Wikimedia production, and let that generate a week or two worth of log data to analyze.