
HTTP Security headers you should be using - relaxnow
http://ibuildings.nl/blog/2013/03/4-http-security-headers-you-should-always-be-using
======
stephenr
> By default jQuery sends the X-Requested-With header. It was thought that the
> mere presence of this header could be used as a way to defeat Cross-Site
> Request Forgery.

By who? Who thought the mere presence of an arbitrary header made the request
"safe"?

Seriously, who the fuck thought this was a good idea? I have so far seen one
single use for X-Requested-With - returning a page as "content only" \- i.e.
omitting the header, nav, footers etc for XHR calls.

~~~
simonw
Loads of people thought it was a good idea. Traditional CSRF attacks work by
pointing an HTML form on an evil third party site at an endpoint on the
trusted site. HTML forms can't include custom HTTP headers, and you can't make
Ajax requests (which can have custom headers) to different domains due to the
same-origin policy - so the presence of an X-Requested-With header should be
enough to "prove" that the request came from the same domain as you and not
from a site run by an attacker.

Unfortunately certain versions of the Flash and JavaScript plugins allow
requests to be made to other domains with custom headers, which left CSRF
holes open.

~~~
michaelmior
What do you mean by "JavaScript plugin"?

~~~
richbradshaw
Think it's a typo for Java.

~~~
michaelmior
Ah, that makes sense! Been such a long time since I've run a Java applet that
I don't think about them anymore.

------
jdbernard
Great article. A lot of times these "you should be doing this" articles are
really annoying. It is rarely true that some advice is good for all
situations. This article, however, takes the time to explain, list the
purpose, and point out relevant caveats for each header. I was not aware of
all of these headers, so thank you for bringing them up!

~~~
relaxnow
As an author that doesn't write publicly all that often, thank you for your
kind words. Lots of feedback is amazing in that it helps me grow, but the
occasional compliment from a stranger does feel really really good.

------
nodesocket
Can you specify domain wildcards in Content-Security-Policy script-src? For
example:

    
    
        Content-Security-Policy: script-src 'self' *.somedomain.com
    

Also, while it looks great, usually its very difficult to integrate this
header, without breaking existing JS functionality. For example, if you set
this header, inline JavaScript will not be executed, this includes added event
methods directly on DOM elements. Also eval() and writing setTimeout() and
setInterval() like:

    
    
        window.setInterval("alert('hi')", 10);
    

Are forbidden from executing as well. Finally, using 3rd party libraries
(Mixpanel, Google hosted libraries, Intercom.io) becomes nearly impossible
without explicitly whitelisting domains in the header (a huge hassle to
maintain).

~~~
yeukhon
_Can you specify domain wildcards in Content-Security-Policy script-src?_

Yes. You may. [http://www.w3.org/TR/CSP/#source-
list](http://www.w3.org/TR/CSP/#source-list) See the _host_ ABNF grammar.

 _while it looks great, usually its very difficult to integrate this header,
without breaking existing JS functionalit_

I haven't read much about 1.1 but as far as I know nounce and hash added to
1.1 is to deal with whitelisting inline scripts.

Please see [http://w3c.github.io/webappsec/specs/content-security-
policy...](http://w3c.github.io/webappsec/specs/content-security-policy/csp-
specification.dev.html#nonce-usage-for-script-elements)

Reference:
[https://bugzilla.mozilla.org/show_bug.cgi?id=855326](https://bugzilla.mozilla.org/show_bug.cgi?id=855326)

[https://bugs.webkit.org/show_bug.cgi?id=89577](https://bugs.webkit.org/show_bug.cgi?id=89577)

[http://lists.w3.org/Archives/Public/public-
webappsec/2013Jun...](http://lists.w3.org/Archives/Public/public-
webappsec/2013Jun/0059.html)

Also, if you are interested in client-side security, Mike West (from Google,
one of the editors of CSP) has given a talk recently.
[http://www.parleys.com/play/529bee0be4b039ad2298ca0b](http://www.parleys.com/play/529bee0be4b039ad2298ca0b)

 _edit_ remember that the support of 1.1 is relatively low and incomplete as
the webappsec group is voting on whether moving it to WD (working draft or
not). So for cross-browser compatibility, you are still better off with 1.0
which is at this point very stable in major browsers.

~~~
michaelmior
Awesome. Thanks for the note about version 1.1 of the standard. Wasn't aware
nonces and hashing were added.

------
j_baker
Content-Security-Policy is a tricky one. For starters, enabling CSP if you're
using Angular causes a _30%_ slowdown[1]. Secondly, a lot of performance
optimizations can be gained by inlining JavaScript. The latter one can be
circumvented using SPDY server push, but that isn't widely used yet.

[1]
[http://docs.angularjs.org/api/ng.directive:ngCsp](http://docs.angularjs.org/api/ng.directive:ngCsp)

~~~
scott_karana
Wow. There are more implications than I would have guessed with CSP. Thanks
for pointing that out!

------
recxjdv
We wrote an extension for Google Chrome which provides a toolbar interface for
testing extensions on a page. It looks at the HTTP security headers,
enumerating the configured values and provides guidance on the most secure
settings. Other things like meta data and form fields with security specific
settings are also reported. If you're a developer, or software tester (or
security professional) then you might find it a useful addition to your
toolbox.

Details here:

[http://www.recx.co.uk/products/chromeplugin.php#httpheaderan...](http://www.recx.co.uk/products/chromeplugin.php#httpheaderandcookie)

Or search for 'Recx HTTP Header and Cookie Security Analyser'

~~~
mastre_
Nice work!

------
sheraz
Sorry for brevity as im posting from mobile, but you should have a look at
OWASP page on usedul http headers

here:

[https://www.owasp.org/index.php/List_of_useful_HTTP_headers](https://www.owasp.org/index.php/List_of_useful_HTTP_headers)

------
michaelmcmillan
I must admit it is a little ironic that your site doesn't use the security
headers you advocate.

~~~
tptacek
Tell me, which of the four headers he talked about --- CSP, XFO, XCTO, and
HSTS --- are going to cause serious problems for a blog?

~~~
michaelmcmillan
The directory entries at
[http://ibuildings.nl/robots.txt](http://ibuildings.nl/robots.txt) suggest
that they're hosting much more than a blog on that domain.

Edit: As others pointed it out, it's a Drupal installation. Trusting Drupal to
be 100% safe in regards to malicious attacks is not a good idea. I know this
is nitpicking, it is however still ironic.

[http://www.cvedetails.com/vulnerability-
list/vendor_id-1367/...](http://www.cvedetails.com/vulnerability-
list/vendor_id-1367/product_id-2387/Drupal-Drupal.html)

~~~
yeukhon
It's a drupal-powered site. It's no different from WP though IMO.

------
masklinn
> 2\. X-FRAME-OPTIONS

Please don't use that one _everywhere_ , frame-based embedding is very useful
in e.g. web-based feed reader (provides the original view of the site without
having to go out of the reader and into a new tab).

~~~
relaxnow
Unfortunately, as the web stands today, for our developers I do advocate
including it by default, unless a specific use-case comes up to not include
it.

While for a simple content page allowing for framing should be okay, the truth
is very very few pages are actually purely content. As soon as you have
something like a comment form there is a chance that framing it could be used
to reveal some private information (autofill / password manager leakage). And
who is going to manage what pages are framable and what aren't? The customer
would need a UI and training and developers can't always see what will be
hosted on a page.

Also, as an advertiser I would very much like you to visit the full page
instead of trying to view it through some limited frame, cutting off the
sidebar with ads.

------
abbot2
Am I the only person who thinks that relying on client behaviour for
"security" is, well, a bit naive?

~~~
callahad
It's part of "defense in depth." Mess up one input validation? No problem,
your CSP prevents client-side execution of injected scripts for most users.

Returning user, temporarily on an untrustworthy network? No problem, your HSTS
header ensures they only attempt to talk to you over SSL.

It's the same reason you should set cookies to `secure; HttpOnly` -- you don't
_expect_ untrustworthy scripts to run on your page, but if they somehow do,
you've got a second line of defense.

------
kennu
Would these headers break ads that come from unpredictable sources through ad
networks?

~~~
billyhoffman
Content-Security-Policy would break ads. That's the main reason why so few
sites use it.

X-Frame-Options is fine, since modern ads use JS and not IFRAMEs.

X-Content-Type-Options is fine because you are essentially telling the browser
to trust the mime-type and not speculatively parse the resource. You know what
the mime-types should be so no problem here

Strict-Transport-Security is fine as well. It also has the added benefit of
forcing SSL for all traffic, and thus could be used to force SPDY instead of
HTTP for 50%+ of a website's visitors, which is a huge performance win.

~~~
yeukhon
The only downside of Strict-Transport-Security is that you must have at least
visited the HTTPS endpoint once.

Therefore, the sane way is to do 301 redirect from all HTTP to HTTPS and HTTPS
response header must include Strict-Transport-Security.

~~~
mischa_u
Should the HTTP response also include the Strict-Transport-Security header?

~~~
revasm
No:

    
    
      Note: The Strict-Transport-Security header is ignored by the browser when your site is
      accessed using HTTP; this is because an attacker may intercept HTTP connections and
      inject the header or remove it.  When your site is accessed over HTTPS with no
      certificate errors, the browser knows your site is HTTPS capable and will honor the
      Strict-Transport-Security header.

[https://developer.mozilla.org/en-
US/docs/Security/HTTP_Stric...](https://developer.mozilla.org/en-
US/docs/Security/HTTP_Strict_Transport_Security)

Also read RFC 6797, section 7.2 in particular.

    
    
      An HSTS Host MUST NOT include the STS header field in HTTP responses conveyed over
      non-secure transport.
    

and

    
    
      If an HSTS Host receives an HTTP request message over a non-secure
      transport, it SHOULD send an HTTP response message containing a
      status code indicating a permanent redirect, such as status code 301
      (Section 10.3.2 of [RFC2616]), and a Location header field value
      containing either the HTTP request's original Effective Request URI
      (see Section 9 ("Constructing an Effective Request URI")) altered as
      necessary to have a URI scheme of "https", or a URI generated
      according to local policy with a URI scheme of "https".

[https://tools.ietf.org/html/rfc6797](https://tools.ietf.org/html/rfc6797)

------
nickknw
> How would you like to be largely invulnerable to XSS? No matter if someone
> managed to trick your server into writing <script>alert(1);</script>, have
> the browser straight up refuse it?

I don't quite get how this header makes you invulnerable to XSS, would someone
mind explaining?

It seems like it only prevents XSS attacks from loading remote javascript
files. What's to stop the attacker from just injecting the entire script
inline? If you can get a small piece of javascript to execute you should be
able to get a larger piece to execute just fine.

I can see how it makes XSS more inconvenient, but I don't understand how it
makes you largely invulnerable to it.

~~~
UnoriginalGuy
Inline Javascript is outright banned by default. Read the HTML5Rocks article
they linked, it is much more comprehensive and answers most of the questions
like that that I had.

~~~
nickknw
Ahh, now that makes sense, thanks! The HTML5Rocks article cleared up my
concerns.

For anyone reading this later, it was the section starting with this
paragraph:

Inline Code Considered Harmful

It should be clear that CSP is based on whitelisting origins, as that’s an
unambiguous way of instructing the browser to treat specific sets of resources
as acceptable and to reject the rest. Origin-based whitelisting doesn’t,
however, solve the biggest threat posed by XSS attacks: inline script
injection. If an attacker can inject a script tag that directly contains some
malicious payload (<script>sendMyDataToEvilDotCom();</script>), the browser
has no mechanism by which to distinguish it from a legitimate inline script
tag. CSP solves this problem by banning inline script entirely: it’s the only
way to be sure.

------
jimmyislive
not bad..i seem to have got at least 3 of them right :)

[http://jimmyislive.tumblr.com/post/67125455740/securing-
ngin...](http://jimmyislive.tumblr.com/post/67125455740/securing-nginx)

------
jimktrains2
* CONTENT-SECURITY-POLICY So, other than sloppy sanitation, what's the use?

* X-FRAME-OPTIONS I feel like the number of times this has prevented a useful action vs prevented a bad action is many:0

* X-CONTENT-TYPE-OPTIONS So, instead of browsers actually honoring the Content-Type header, we have to ask with a "pretty please"?

* STRICT-TRANSPORT-SECURITY Doesn't prevent problems on a first connect, but definitely a good idea (if your site supports SSL that is:)). Blanket TLS is a good thing.

Just my 2¢

~~~
relaxnow
* CSP is actually the header that most security professionals are the most excited by (in my experience) as it gives you more control over what resources are and are not allowed. Especially when you're thinking of a future where you want to securely 'mash up' content, being able to set policies is essential.

* XFO, it you're doing API first there really is very little reason to frame a page. Maybe Twitter style widget support? But in that case you can have a separate URL for that.

* XCTO, yes, welcome to the 'organic' web :p

* HSTS, the first connect is difficult, maybe one day via DNSSec? But I must confess to know very little about DNSSec.

~~~
jimktrains2
I wasn't saying HSTS is useless, just pointing out one of the issues with it.
I think HSTS a great thing!

With XFO, doing something like adding 'reddit.com/' before the domain to see
if it's been submitted becomes much more computationally intensive on reddit's
side if they can't just put it in a frame. This is where I run into issues
mostly, with tools such as that. That said, there are other things it could do
(take me to a submit page or a discussion page instead of framing the page).
And frames suck anyway, so there is that.

I can see the usefulness in CSP, I just feel like it's a band-aid on larger
problems.

~~~
yeukhon
_X-FRAME-OPTIONS I feel like the number of times this has prevented a useful
action vs prevented a bad action is many:0_

I am rather curious where did you get this claim? Any stories I should check?

And also what's the larger problem? Again, I'd really love to hear you
elaborate on your thoughts.. thanks.

~~~
jimktrains2
As for XFO, I specifically said that that was my opinion and my experience. I
even give a specific example: adding reddit.com/ before the domain of
hackernews, for instance, won't let reddit put it in a frame (in order to put
the reddit toolbar above it). I've only ever encountered tools such as that
breaking because of XFO.

Also, it's my user-agent, it's suppose to do what _I_ want it to do, not what
the content author wants it to do, and I can't find a way to disable honoring
XFO.

For CSP, one example of a larger problem would be excepting and storing
unsanitized input. If it's going out to the user as (otherwise executable)
javascript, are there other places that you're placing unescaped user-
submitted data that could be an issue (a sql statement perhaps or the API to a
site who trusted you to sanitize things (although they shouldn't)?).

