Page MenuHomePhabricator

Set default CSP header in service template to "default-src 'none'"
Open, NormalPublic

Description

I think having a template with a strict default (ideally, default-src 'none') would be best for both auditing and maintaining.

In T109023, @GWicke is arguing that most services should allow RESTBase to set the headers. But I favor setting a strict policy in the service template because:

  1. It encourages developers to justify adding policies instead of me asking why they can't be more strict during security review.
  2. The CSP standard doesn't look like it's going to change, nor (from what I can tell) is there strong sentiment by browsers to re-interpret any of the directives in the standard, so I think it should be very rare we're going to need a sweeping change to the default policy for all services
  3. RESTBase is always going to need a minimum policy that isn't essentially deny-all, which as I put in #1, is not the position I want to start from
  4. I believe RESTBase is currently setting style-src 'unsafe-inline' and frame-ancestors 'self' [1], so any new service should override the CSP, unless they have good reason for allowing inline styles and iframing.

[1] -

csteipp@herou:/tmp> curl -s -I 'https://en.wikipedia.org/api/rest_v1/page/html/Main_Page' | grep "^Content-Security-Policy:"
Content-Security-Policy: default-src 'none'; media-src *; img-src *; style-src http://*.wikipedia.org https://*.wikipedia.org 'unsafe-inline'; frame-ancestors 'self'

Event Timeline

csteipp created this task.Sep 8 2015, 4:24 PM
csteipp raised the priority of this task from to Needs Triage.
csteipp updated the task description. (Show Details)
csteipp added projects: Security-Team, Services.
csteipp added subscribers: csteipp, GWicke.
Restricted Application added a subscriber: Aklapper. · View Herald TranscriptSep 8 2015, 4:24 PM

I think there are two discussions here:

  1. how strict our baseline CSP headers should be for HTML and SVG, and
  2. where we should ensure that strict CSP headers are set.

My argument is that it's easier to maintain and audit a really strict policy (like setting the exact domains to load images from) if we limit the number of places that enforce it. We can and absolutely should tighten down the default RESTBase policy to be the safe baseline we are looking for. Exceptions should be clearly documented, and should be justified.

Another practical aspect is that CSP headers should be consistently applied to both stored and dynamically generated content. Since CSP headers can change they should be config-driven, which means that we need to maintain this configuration in RESTBase in any case.

I think there are two discussions here:

  1. how strict our baseline CSP headers should be for HTML and SVG, and

I think you're calling out a distinction here about the 2 types of content we serve from our services,
1.1) Pages that are served as top-level or iframed html (I think that is what you're referring to as "HTML"), and SVG's which are closely related to that use as well in how browsers use CSP to limit what the code can do.
1.2) json, and other content, that is loaded either from a backend server or from the client-side javascript, which is then used to construct the page.

The majority of services that I've reviewed so far fall into 1.2-- CX Server, Citoid, Graphoid (currently), almost the entirely of Maps, and all but one of the MobileApps entrypoints. Iirc, almost all of parsoid falls into this too, with only a fallback use of iframing content for IE. For all of these, we should set default-src 'none' as the only CSP header to indicate that browsers should only ever interpret this data as content.

Restbase, and I believe mathoid and the next itteration of graphoid, fall into 1.1, where we need (relatively) liberal CSP headers to allow the browser to interpret the content as top-level HTML and load in images/styles/scripts from all domains.

  1. where we should ensure that strict CSP headers are set.

So using RESTBase's CSP headers as the default for the "1.2" services seems like the wrong place, since the headers are never going to be as strict as we should set them, and by numbers seem to be the more common case (feel free to correct me if that's no the case).

To encourage developers to do the right thing, what about having in the service template a default of "default-src 'none'", then have a commented out configuration that matches RESTBases with comments recommending that for pieces of their service that need to serve HTML, and a similar configuration for SVG? Then if the developer removes them all (or more likely, something changes in the template and the headers aren't sent for some reason), RESTBase will still add headers in production and give a mostly sane policy.

That would mean some duplication of code, but worst case your team is updating RESTBase and the template, and then other teams are just updating to the latest template.

GWicke added a comment.EditedSep 9 2015, 5:33 PM

So using RESTBase's CSP headers as the default for the "1.2" services

Currently, we actually don't set any CSP headers for non-HTML/SVG responses. The reasoning behind this is that there seems to be no overlap between content type sniffing and CSP support.

However, you rightly pointed out that re-dressing attacks could still be an issue with iframes. So, we should re-add restrictive CSP headers disabling any framing for non-HTML/SVG responses.

We should also tighten down the default headers for HTML/SVG to only allow images and media from our own domains.

Edit: This is now tracked in T112586: Unconditionally set up restrictive CSP headers for non-HTML/SVG content in RESTBase.

Note that the current policy is also violated by embedded image data URIs.

Error: Refused to load the image 'data:image/svg+xml,..' because it violates the following Content Security Policy directive: "img-src".

May need to whitelist data: there.

Note that the current policy is also violated by embedded image data URIs.

I'd argue this is desirable, and individual services should override the default if they are embedding images.

Unless the service template serves something that has embedded images by default?

Note that the current policy is also violated by embedded image data URIs.

Error: Refused to load the image 'data:image/svg+xml,..' because it violates the following Content Security Policy directive: "img-src".

May need to whitelist data: there.

Which service is that? Mathoid?

Unless the service template serves something that has embedded images by default?

Nope. It only serves various JSON data (service name and version, the spec, etc) and robots.txt.

GWicke triaged this task as Normal priority.Oct 12 2016, 9:02 PM
GWicke edited projects, added Services (later); removed Services.