Skip to content
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

Add security headers to minimize XSS damage #292

Merged
merged 1 commit into from
May 8, 2016
Merged

Add security headers to minimize XSS damage #292

merged 1 commit into from
May 8, 2016

Conversation

xPaw
Copy link
Member

@xPaw xPaw commented May 1, 2016

This disallows execution of scripts from other domains, inline scripts and use of eval. Also adds X-Content-Type-Options: nosniff on all requests.

@xPaw xPaw added the Type: Feature Tickets that describe a desired feature or PRs that add them to the project. label May 1, 2016
@astorije astorije self-assigned this May 1, 2016
@astorije
Copy link
Member

astorije commented May 3, 2016

@xPaw, I rebased this to merge conflicts :-)
Will review very soon, tomorrow hopefully (I need to check a thing or two before).

@astorije astorije added the Type: Security Security concern or PRs that must be reviewed with extra care regarding security. label May 4, 2016
@@ -91,6 +97,7 @@ function index(req, res, next) {
config
);
var template = _.template(file);
res.setHeader("Content-Security-Policy", "default-src *; style-src * 'unsafe-inline'; script-src 'self'; reflected-xss block");
Copy link
Member

@astorije astorije May 5, 2016

Choose a reason for hiding this comment

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

I really like this policy! A few minor comments/questions:

  • Content-Security-Policy is defined on page-by-page basis. Any reason why you put it here instead of inside your allRequests function?
  • * is the default value for everything so we don't need to specify it for default-src. Was there a specific reason why you did so?
  • I'm not sure I fully understand reflected-xss block: is it to enforce Chrome's filter against executing code that exists in the URL (for example) onto all browsers that would not enforce it by default?
  • It's possible that some or all of the following directives could be added, provided that I'm not entirely wrong:
    • Any reason against connect-src 'self'; considering how the server connects to the client (at least currently)?
    • I think we could set child-src 'none'; object-src 'none'; as well, as I don't think we need framed content or Flash content or etc.
    • We can set form-action 'self'; as well, or maybe even form-action 'none'; as none of the forms get actually submitted.
    • We might be able to set frame-ancestors 'none'; but maybe that could restrict usage for some users? (Thinking of the integrations like Bytesized or Cozy or whatever, maybe someone does crazy stuff to display their apps?)
    • We can set media-src 'self' as we don't embed videos or similar (but we do load one sound from within the app)

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm not sure there's any need to send CSP on all requests (all other requests besides index.html would be static content).

I'm not sure I fully understand reflected-xss block

reflected-xss : Instructs a user agent to activate or deactivate any heuristics used to filter or block reflected cross-site scripting attacks, equivalent to the effects of the non-standard X-XSS-Protection header.

I've also didn't set extra hardened directives because I don't know what we would want to allow for eventual plugins to do.

* is the default value for everything so we don't need to specify it for default-src

Explicitness. We could eventually set it to self instead, and configure other directives as needed.

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure there's any need to send CSP on all requests (all other requests besides index.html would be static content).

Yeah OK, we'll adjust later if necessary.
I know that we essentially only send index and then the websocket takes over, but I'm thinking that other fallbacks from Socket.io might be worth "policying". But again, I don't think Socket.io would send this policy even if we set if with all requests (because it does go through Express).

reflected-xss : Instructs a user agent to activate or deactivate any heuristics used to filter or block reflected cross-site scripting attacks, equivalent to the effects of the non-standard X-XSS-Protection header.

OK so basically it's unnecessary in Chrome because filters are already enabled, but I don't know for other browsers.

I've also didn't set extra hardened directives because I don't know what we would want to allow for eventual plugins to do.

Agreed, but what about hardening at the moment and adapting when packages are a reality (or start to be one)?
After all, it's not set in stone, and some directives of the policy might not change anyway (especially connect-src and form-action, maybe child-src).

Explicitness. We could eventually set it to self instead, and configure other directives as needed.

Good point, to keep in mind.

@astorije
Copy link
Member

astorije commented May 6, 2016

I'm essentially 👍 but I would prefer if we harden things as suggested in the comments before merging this PR. Again, nothing set in stone, totally OK to re-evaluate when plugins show up, but in the meantime, there is no need to keep the doors open.

@astorije
Copy link
Member

astorije commented May 6, 2016

For the record, I had to catch up on the details of CSP before reviewing this, and if someone is looking for a good intro, http://www.html5rocks.com/en/tutorials/security/content-security-policy/ is really good.

@xPaw
Copy link
Member Author

xPaw commented May 6, 2016

I've added child-src 'none'; object-src 'none'; form-action 'none'; referrer no-referrer; and removed reflected-xss.

@@ -14,7 +14,7 @@ function uri(text) {
return url;
}
var split = url.split("<");
url = "<a href='" + split[0].replace(/^www/, "//www") + "' target='_blank'>" + split[0] + "</a>";
url = "<a href='" + split[0].replace(/^www/, "//www") + "' target='_blank' rel='noopener'>" + split[0] + "</a>";
Copy link
Member Author

Choose a reason for hiding this comment

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

https://mathiasbynens.github.io/rel-noopener/

Thought it would be a good idea to include along with referrer no-referrer

Copy link
Member

Choose a reason for hiding this comment

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

Great read! And great idea!

@maxpoulin64
Copy link
Member

Looks all good to me, 👍

@astorije did you still want to hold the merge?

@astorije
Copy link
Member

astorije commented May 8, 2016

Nop, let's do this!

@astorije astorije merged commit c7fb388 into master May 8, 2016
@astorije astorije deleted the xpaw/csp branch May 8, 2016 04:42
@astorije astorije added this to the ★ Next Release milestone May 15, 2016
matburnham pushed a commit to matburnham/lounge that referenced this pull request Sep 6, 2017
Add security headers to minimize XSS damage
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Feature Tickets that describe a desired feature or PRs that add them to the project. Type: Security Security concern or PRs that must be reviewed with extra care regarding security.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants