Page MenuHomePhabricator

Add support for Content-Security-Policy (CSP) headers in MediaWiki
Open, MediumPublic

Description

A significant portion of security vulnerabilities in MediaWiki are XSS vulnerabilities. Content-Security-Policy is an HTTP header that allows you to disable certain HTML features, which are commonly used when exploiting XSS vulnerabilities. Adopting CSP has the potential to make MediaWiki sites significantly more safe.

See https://www.mediawiki.org/wiki/Requests_for_comment/Content-Security-Policy for the full proposal. See http://www.w3.org/TR/CSP2/ for the official CSP spec.

Summary:

  • CSP disables all the inline ways of executing javascript (e.g. <img onerror="alert(1)"> )
    • Only way that's left <script src="foo"> where foo is a whitelist, or <script nonce="bar"> where bar is in the http header
    • From our perspective, the primary benefit is when the attacker can inject non whitelisted attributes but not full on script tags, since users control javascript on our domain (and would riot if we took that away from them). It will also allow us to make super focused blacklists, concentrating just on <script>
  • This will break a lot of old gadgets. JS code following modern conventions mostly won't break. Nonetheless this will probably make a lot of local admins angry. I think this cost is worth the vast benefits, however we will need to provide support to communities to help them deal with the change
    • On the bright side, this will force people to update old code that is using dangerous patterns. Local on-wiki JS is definitely one of our weakest spots security wise.
  • We can enable CSP piece by piece, starting non-controversial, and working our way up. We can also enable a report-only mode to see what will break beforehand.

Related bugs: T117618, T28508, T120888, T130748

Details

Related Objects

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes
Krinkle lowered the priority of this task from High to Medium.Oct 13 2016, 8:26 PM
Krinkle removed Krinkle as the assignee of this task.Mar 8 2017, 12:21 AM
Krinkle added a subscriber: Krinkle.

@Bawolff What's the status of this? At least from this task it looks like it's been stalled for quite a while?

@Bawolff What's the status of this? At least from this task it looks like it's been stalled for quite a while?

Basically many other tasks came up, and I haven't had a chance to get back to this. At this stage, the next most immediate task to do on this is rebase the gerrit patch, and get that merged

K4-713 added a subscriber: K4-713.Mar 16 2018, 6:38 PM
He7d3r added a subscriber: He7d3r.Mar 19 2018, 1:58 PM

Change 253969 merged by jenkins-bot:
[mediawiki/core@master] Initial support for Content Security Policy, disabled by default

https://gerrit.wikimedia.org/r/253969

Do we want to mark this as Resolved now, or wait until we've tested it in production a bit and addressed any follow-ups / fixes?

This is probably more of an epic task. Just because the patch is merged doesnt mean we can fully put CSP in enforce mode tomorrow (indeed initial rollout plan wont include removing unsafe-inline)

A more detailed rollout plan will be forthcoming

Rxy added a subscriber: Rxy.May 15 2018, 10:40 AM

The errors I am getting are like this:

[16-May-2018 14:55:23 UTC] PHP Notice:  ResourceLoader::makeInlineScript did not get nonce. Will break CSP [Called from ResourceLoader::makeInlineScript in /srv/mediawiki/tags/2018-05-16_14:06:40/includes/resourceloader/ResourceLoader.php at line 1513] in /srv/mediawiki/tags/2018-05-16_14:06:40/includes/debug/MWDebug.php on line 309

Is it possible to make them more informative what is the source?

It probably means that some extension hasnt been updated for makeInlineScript() new arguments. (I guess this is a deprecation in a sense and i should email wikitech-l). Im travelling today and cant really look into it today...

Nirmos added a subscriber: Nirmos.May 17 2018, 9:43 PM
MaxSem added a subscriber: MaxSem.May 18 2018, 1:35 AM

Change 452407 had a related patch set uploaded (by Brian Wolff; owner: Brian Wolff):
[operations/mediawiki-config@master] Adjust CSP settings. For this stage allow inline but restrict src

https://gerrit.wikimedia.org/r/452407

Change 452407 merged by jenkins-bot:
[operations/mediawiki-config@master] Adjust CSP settings. For this stage allow inline but restrict src

https://gerrit.wikimedia.org/r/452407

Ok, so status update. We are now testing what we intend to be the initial deployment (Still allow inline scripts, but block loading of external stuff) on group0 wikis (e.g. https://test.wikipedia.org and https://mediawiki.org )

The description mentions some onerror attribute that I've never heard of:

CSP disables all the inline ways of executing javascript (e.g. <img onerror="alert(1)"> )

Will this also affect onclick attributes?

The description mentions some onerror attribute that I've never heard of:

CSP disables all the inline ways of executing javascript (e.g. <img onerror="alert(1)"> )

Will this also affect onclick attributes?

So our plans have changed a little bit since this bug was initially written. First step we are just going to block external stuff from non-Wikimedia domains. We expect that this transition is going to be complicated enough and take quite a bit of time, so for now we are dropping the disable inline javascript (Which includes disabling all attributes starting with on including onclick). Eventually I'd like to see the disabling of onclick and friends, but that's far in the future at this point.

RP88 added a subscriber: RP88.Aug 19 2018, 8:03 PM
Base added a subscriber: Base.Aug 19 2018, 8:05 PM
FDMS added a subscriber: FDMS.Aug 19 2018, 8:08 PM
Joe added a subscriber: Joe.Aug 22 2018, 8:46 PM
daniel added a subscriber: daniel.Sep 5 2018, 7:57 PM

There seems to be quite a bit of activity on this, but the RFC is still tagged as "under discussion". As far as I know, some parts of the RFC were approved, while other where still being discussed. What'S the status here? What remains to be done? What are the plans? Is this ready for a final discussion?

There seems to be quite a bit of activity on this, but the RFC is still tagged as "under discussion". As far as I know, some parts of the RFC were approved, while other where still being discussed. What's the status here? What remains to be done? What are the plans? Is this ready for a final discussion?

I wasn't aware it is still tagged under discussion - I thought it was largely "approved".

My plans have evolved somewhat since this was originally discussed. my current draft plan is https://www.mediawiki.org/wiki/User:BWolff_(WMF)/CSP_plan For the moment I want to drop the anti-XSS (no "unsafe-inline") parts and concentrate solely on enforcing no external loads (for privacy, and also ensuring better audit trail in event of MediaWiki:Common.js).

One aspect of this is user's who want to access external apis via JS (e.g. like the google calendar gadget at office wiki). What I would like to do is have a preference so that users who want to do this sort of thing can opt-out of the defence well still allowing us to protect the average user (still restricting script-src in all cases. I don't have the precise details worked out yet). This is something that I would like to bring up with TechCom and can use discussion.

TechCom has marked this approved, but there needs to be another RFC specifically related to the registry to opt-in and connect to 3rd party services. This was not considered as part of the original decision.

This is probably more of an epic task. Just because the patch is merged doesnt mean we can fully put CSP in enforce mode tomorrow (indeed initial rollout plan wont include removing unsafe-inline)
A more detailed rollout plan will be forthcoming

I think that rollout/apply-in-prod is better located at T28508 rather than here?

This is hopefully one of the last RFCs to be all-encompassing of a larger goal. Based on the 8 stages documented at the original RFC at https://www.mediawiki.org/wiki/Requests_for_comment/Content-Security-Policy, I believe that it can be summarised into four high-level stages of which three should be covered an RFC:

  1. The creation of the report-ingestion API.
  2. The immediate enforcing of a very strict CSP policy in browsers when viewing content directly on upload.wikimedia.org (e.g. original SVGs).
  3. Various logging and data gathering stages.
  4. The enforcing of CSP on page views, and its requirements (what default policy to use, how and what to change in core to abide by the policy, how to whitelist additional origins with the user's permission).

The first two bullet points I believe were approved by TechCom in 2016 ("Stage 0-3"), and have since been implemented.

The third bullet point represents the middle stages involving configuration and logging that don't require an RFC. The collecting and storing of data may have needed coordination with Analytics, Legal and/or SRE in terms of what and how long we retain (privacy), how much data in bytes to store and for how long (storage space requirements for Logstash and mwlog servers). This uses existing systems in ways they are designed for, of which additional use does not require architectural approval.

The fourth bullet point should be covered by an RFC. Some of the initial work in this has already started (with TechCom advising directly in Gerrit, https://gerrit.wikimedia.org/r/253969), but it's also clear that there's still a lot of details to be figured out. I'd recommend marking this task as resolved and creating a new task for that work.

A more detailed rollout plan will be forthcoming

I think that rollout/apply-in-prod is better located at T28508 rather than here?

Agreed :)

Can we exempt localhost URLs from this? It would impede user script development.

(I don't know if this is the right place to ask; let me know if it isn't.)

kaldari added a subscriber: kaldari.EditedMay 15 2019, 2:56 AM

@Bawolff - What is now the correct way to import images to Commons from 3rd party websites on the client-side? For example, when I currently try to import images from Flickr using UploadWizard, I get the following error:

[Report Only] Refused to connect to 'https://api.flickr.com/services/rest/?&format=json&nojsoncallback=1&method=flickr.photos.licenses.getInfo' because it violates the following Content Security Policy directive: "default-src 'self' data: blob: https://upload.wikimedia.org meta.wikimedia.org *.wikimedia.org *.wikipedia.org *.wikinews.org *.wiktionary.org *.wikibooks.org *.wikiversity.org *.wikisource.org wikisource.org *.wikiquote.org *.wikidata.org *.wikivoyage.org *.mediawiki.org wikimedia.org". Note that 'connect-src' was not explicitly set, so 'default-src' is used as a fallback.

Should we add api.flickr.com to the CSP or does UploadWizard need to be refactored somehow?

Shouldn't that call be going via our API and urldownloader hosts?

kaldari added a comment.EditedMay 16 2019, 4:07 AM

@Krenair - The actual uploading is handled by urluploader, but UploadWizard has to do a lot of communicating with Flickr's API beforehand for information. Is there some kind of proxy API it should be using for that?

@Krenair - The actual uploading is handled by urluploader, but UploadWizard has to do a lot of communicating with Flickr's API beforehand for information. Is there some kind of proxy API it should be using for that?

Ideally it would be done through the server side to preserve user privacy. If it was required to be on client side, (and there was the neccesary privacy approval) the idea was that there would be an api extensions could use to add domains to the whitelist for a specific [special] page. Currently this exists via hooks, but the original plan i had was that a more useful internal api would be added for specific exemptions on specific urls.

SD0001 added a subscriber: SD0001.Oct 28 2019, 8:00 AM

Localhost URLs should be added to the CSP. Not being able to load javascript from a local server would severely impede development of user scripts and gadgets. Thanks.

Kghbln added a subscriber: Kghbln.

Localhost URLs should be added to the CSP. Not being able to load javascript from a local server would severely impede development of user scripts and gadgets. Thanks.

After discussing this with several script developers, its clear that being able to load scripts from localhost is important to this group. I don't want to allow that generally, but I believe an appropriate compromise would be to have an option that people can opt in to, to allow loading scripts from localhost. More details about how that will work will come once it actually happens.