
let's all welcome Benjamin Haring with HTTP security headers a technology history through scar tissue hello hello hopefully we got the slides up here in just a little bit hopefully you guys are here to talk about HTTP security headers if you're not looking for that you're in the wrong room you better run downstairs to the theater real quick all right anyway let's start my name is Benjamin Herron I'm a sans Community mentor I help out a little bit here with b-sides SS I work at the company that bought you all lunch yesterday but you're not here to learn about me let's move on get to the content first a little bit of housekeeping things if you are wanting
to capture the slides feel free to take photos post them on Twitter don't get anybody else in the shot but if you want to just go straight to the information there's pdfs already uploaded to this event here in sched you can follow along in real-time whatever else you'd like also we're gonna do questions today without this clicker let's try something else all right so if you have a question we're trying something a little bit new here at b-sides we're gonna do slide oh you can just open that up on your phone enter in b-sides of F 2019 and the proctor you can vote on what questions you want if there's some time at the end
we'll definitely go over those and anything else feel free to just yell at me at Twitter I will generally enjoy going through all the posting you have to tell at me once we get done with this talk the handles right there but with that let's get into the content so I really like HTTP security headers because they are a living record of history of all the times where people have gone and went wait that's super bad and it always kind of follows the same pattern where someone somewhere finds something bad on the internet and it turns out that in order to shut off that bad thing it's gonna break a lot of functionality on the internet so what we
always come up with is oh we'll just have this very special Security header that if you send it will turn on this great security control but it's just gonna be off by default and then wash rinse repeat we keep fighting this over and over again or to put it another way Yarra wizard Hattie and the internet is full of terrible terrible things fortunately we have a browser that's big and strong and has lots of security controls just waiting for you but in order to make it work you have to know the magic words so here's our magic words here's the headers that we're going to be talking about today and let's get straight into it so the first one that kind of jumps
up on the scene is these ex-con tight top options about a decade ago somewhere around December 2008 all right so what's the bad thing so back in the day when people were building web sites browser manufacturers found that people kept on running into this problem of why is my JavaScript just displaying as a text file and not actually running and that issue was as they had uploaded it as plain text Mimmi type weren't on execute about many times so browser manufacturer said you know what we're gonna make this super convenient for you we know what javascript looks like we run it all the time so if you send us a file that looks like it should be executed even if you
set the mini type wrong we'll just go ahead and switch that for you so everything works out just fine well turns out a common security control when you're uploading arbitrary files are letting users upload arbitrary files is you know upload wherever you want but nothing that's executable and then you combine this with this new browser feature that says oh we'll take down executable things and make them executable for you again and surprise surprise you start to have some sort of problem so if you're gonna set this header just go ahead and set it to no sniff which basically says browser don't try to guess anything just do what you're told and then obviously you got
to set your memory types correctly all right moving on the next one that kind of shows up on the scene is this X cross site scripting protection again about ten years old or so and the bad thing that it tries to protect against it's right there in the name now this cross-site scripting protection is not exactly the most intelligent all right all it's doing is really dumb pattern matching where if it sees something that's in the URI and that something is also side the HTML source of the page it things ah that must be cross-site scripting let me go ahead and filter that out and it's stopping just the bare-bones lowest cross-site scripting that you can find now with that the
default of this filter setting is not what I'd recommend that you keep it too the reason for that is that the filter settings are kind of so not the most intelligent that there's actually been CVS issued where the cross-site filter is actually then used to deliver a cross-site scripting payload in addition an attacker really it's trivial to craft a URL that knocks out correct legitimate scripts that are supposed to be there all you got to do is have the attacker add a query parameter set that query parameter to be the script tag that you want to get knocked off the cross-site filter says oh it's the same in both places get rid of it and they can
selectively disable functionality in your site so don't keep it at the default either shut it off entirely and say hey we have better ways to deal with cross-site scripting protection or set it to mode equals block now any time I'm trying to research these kinds of things I like to go out and see well how is this actually looking in the real world so here's a couple of examples from companies with security budgets way way way larger than mine and you can see they don't always agree on what the correct set of security headers are that's because these things do need to be tailored to your organization one thing they both agree on though is that the defaults suck and
you should change them so you can see that Facebook includes the X content type options but Google on their hyper optimized homepage does not and they're fit I dia of that really really basic cross site scripting filter Google says ok we're gonna use it but we're gonna set it to block and Facebook says not we're gonna take care of this another one so with these things you do have to understand the very specifics of your website now moving on the next one that we see is that X frames option that you saw in that previous example this is a little bit newer maybe eight nine years or so something like that and basically it's all about embedding websites in
other websites the frame tag that this was named after is now deprecated but this applies to iframes and objects which I think I frames even though last time I touched them was embedding some Facebook social media feed like eight years ago I don't think it's ever ever going to die it's gonna be with us forever and the bad thing is is obviously if you have a good page embedded inside an attackers web page well then the attacker can do all sorts of nasty stuff so unless your website or web application is designed to be and abetted into other people's pages you probably don't want to let them do that and that's what x-frame options does so
some common good settings are just shut it down straight-up deny or use same origin which says hey you can embed this but only on the same domain that it was loaded from none of this cross-site embedding or you can do a very very specific whitelist with the allow from directive all of those will give you some more security here that said spoiler alert content security policy which we'll talk about right at the end is way better than all of this it's way more customizable way stronger but it's not really interpreted well without older browsers so if you have a public-facing site on the internet and like me have a depressing percentage of your visitors still on Internet Explorer
you're gonna want to send both the X frame options and the content security policy header to make sure you have something that all browsers actually understand next up is strict Transport Security and this is one that I really enjoy because it's around the time when we realized that we didn't have to have X in front of every single custom HTTP header this came out of Moxie Marlinspike demo of SSL strip at blackhat in 2009 I believe and in order to understand what's going on here let's do a walk-through of what what a normal simple browser request is supposed to look like alright so you got your client the client wants to go to example.com they type it into their browser simple
DNS free resolution lets them know the IP address and the default of every single major browser is something that the user happened to type in rather than click is we're going to start over HTTP over an unencrypted session so any major server modern server and built in the past 10 years is only listening on HTTP to say oh whoa whoa wait a sec let's redirect this conversation back to a CH yes which should work just fine the browser's gonna honor it you're gonna do that TLS negotiation and dance with public in private keys I trust it awesome here's the content way to go now that's off everything's working great but let's assume that there's someone not so great surprise
surprise that's large chunks of the internet so if you have someone not so great a person in the middle attack looks like this where the client still requests that domain and they can just straight up and lie about the DNS resolution okay again the default is going to go over HTTP but remember the server's only going to respond with content over HTTP but for the person in the middle attack that doesn't matter it will communicate with the server over HTTP doesn't care about anything just grabs the content and then on the way back inserts whatever a little malicious tidbit it wants and the end client is gonna get that and gonna run it because even
though the server thinks it's only communicating with clients over HTTP the man and that or the person in the middle is able to downgrade that to plaintext HTTP all right so how does strict Transport Security help with this situation all right same deal client can look and still get a faulty DNS record the attacker can still totally lie strict Transport Security doesn't help with that that's a different set of security controls that people are working on what it does do however is if it realizes that strict Transport Security is set for that site it will do an internal redirect to HTTPS before the request ever leaves the browser at which point the attacker can send a garbled cert or whatever and
you're gonna get a certain mismatch and in addition to your regular cert mismatch if strict Transport Security is enabled it's much much harder for the user to just stupidly click through and be like yeah okay whatever all right so if you're gonna be setting this for your site here's what you're gonna do basic version of strict Transport Security is just Mac's age equals expires times in a number of seconds and every single request after that initial headers respond until the time expires is going to be over HTTP now the next level that you can get with that is adding that little pre lookup sorry the include subdomains flag and for include subdomains if you're responding
with that at the root of your site example.com then the browser's gonna treat that strict Transport Security header for all your subdomains mail that example calm or dub dub dub example.com or fubar whatever example.com will get the same strict Transport Security header but here's the thing these two versions work great at protecting your end users the end clients for the second request onwards it can't predict it protect the client from the very first request if you still have a man in the middle that very first request might not realize that strict Transport Security is enabled for your site and on the way back the attacker can both strip out the strict Transport Security header and still downgraded to
http and so the way that we've decided to do this is by excuse me strict Transport Security pre loading which if you do all of the requirements basically every single sub domain on this domain it's gonna be HTTP enabled with a valid cert you can get a max age over a year you can then submit this to the browser manufacturers to have it pre-loaded and pre-loaded basically means you add your site to a really really long text file so what this means is my tiny little blog domain that gets two hits year is on a text file on everyone's computer in this room probably more than once once for Chrome another for Firefox and other
for brave and this is obviously totally sustainable where we're going to just include every single domain that's ever going to be on the Internet now it's seriously though if we do get to a problem where the strict Transport Security preload list is hundreds of gigabytes long that's a problem that I'd like to deal with because that means HTTP is ubiquitous and going absolutely everywhere but that's not the future that we live in now and so we'll have the browser of manufacturers deep figure out what we're gonna do when this file grows to big but until then go ahead and preload your site so that the very first time that a client comes and tries to
talk with you they'll be connected by HTTP before the request ever leads the browser moving on we got refer policy it's one of the more modern only been around for a couple of years and so well the first thing that I don't like about refer policy is that officially codifies in the internet that the original referer header with 3 R's is in fact a typo that we're stuck with forever because it is dealt with using VB fer policy with four R's I kind of wish that we had just decided that refer with 3 R's is a new word that we made up in technology and totally not a typo and refer policy blows up that
fantasy of mine that's not the timeline that we're living when anyway the refer a policy with 3 R's can sometimes leak information about your users to other sites so for those of you who may not be familiar basically every time that someone it clicks on a link or navigate somewhere else the refer policy is set that says hey this person arrived at your site coming from here and that could leak some sensitive information so maybe there's very specific query parameters or URI strings that really identify the user maybe you're running a website that is you know politically sensitive or might be something that your users would like to be really private about or maybe those you are eyes include very
personally identifiable information I remember there was some researchers out of Germany when they realize that ISPs were selling what they said were quote anonymized browsing records at their customers they went and bought a set and we're able to track down individual users because of things like very specific URI Suri's like there's a profile edit page that you could only get to if you were logged in that includes the name of the profile so I log into LinkedIn to edit my profile I get a URI that only I will ever get and that identifies an otherwise anonymous user so if you don't want to think or deal with any sort of information leakage you can use the referrer policy
the specific things that you want to set again is going to depend on your specific site but some good options might include setting it to strict origin which you just slice off the URI that just include the domain name or strict origin when cross origin which will give the full referer header as they're bouncing around inside of your site which is usually helpful for things like user tracking excuse me like various analytics use the full refer header to help you track trace the path that users are going through your site marketing UI folks really enjoy having that information but when you go across to a different site it'll slice off that URI information or you can say hey I
don't want to deal with this crap just shut it off entirely set the nodal referer header that all works all right I want to briefly touch on feature policy without going too in-depth because spoiler alert if you understand content security policy which is coming up right next you understand feature policy it's like content security policy but for features and for features I mean things that are functionality so whether or not your site's gonna use the microphone or geolocation data or video or so on and so forth feature policy is something that you could use to restrict your site to a small subset of features the only problem is is this something that Google came up with and thought was a great
idea and so is totally implemented across every single browser that Google manufacturers or is based on the chromium open source version that they release and everybody else is kind of deciding how this is going to work so in the past couple of months Firefox actually added this functionality but they turned it off by default so but then again everything is becoming the Google Chrome browser so you know maybe this will show up sooner than will exceed but know that it's here this is probably going to be a tool that you can leverage in your toolbox more consistently across your user base within a couple of years it's just something that's coming down the road now with that I want to do a deeper dive
into content security policy because content security policy is the 800-pound gorilla of security headers because when we talk about content security policy the bad thing is somehow somewhere who knows what or why there's some content that's running on your site that you don't there and so content security policy lets you lock down to a very specific whitelist what type of content that you want in your site imagine this like a big bouncer standing outside of a club with a little you know clipboard that lists every single piece of content that is invited to come to the party that is your website and if something shows up that's not on the list they beat them up
and they throw them out and then they send you a report to let them to let you know who tried to force their way into the party and when I say content that's a really generic kind of term what do I mean when I say content I mean content I mean fonts I mean JavaScript I mean CSS I mean images I mean whether or not they're sub resource integrity enabled on everything I mean upgrading HTTP requests to HTTPS who gets to embed you get the idea if there's something that your website is able to do more likely than not that there is a content security policy directive for that specific type of content so let's dive a
little deeper and see how we would build this type of a content security policy header so here's the basic one where you say the default for any type of content is that it's got to come from me and that means the specific origin no other subdomains allowed and we're gonna throw in a report URI which says hey here's the place to send warnings of when I block stuff for you and then the developer runs up inside oh wait wait wait wait we need to be able to connect to Google Analytics for a metric stuff and you say okay no sweat we're gonna add another line to the clipboard guest list great Google Analytics that's a
site that you're now allowed to connect to and everyone's like okay fine oh but wait we have inline JavaScript and this little Facebook Connect widget you're like okay okay we're just gonna add another line and you can see how you can be slowly building out a content security policy as your guest list of who's invited to show up up to your website now I want to outline the unsafe inline for the script source parameter it would be our goal as security professionals to be able to get that out of your content security policy because if you're able to successfully pull that out of your content security policy entire classes of bugs just died your website might have the most horrible
cross-site scripting vulnerabilities known to man but if unsafe in line is not in there an attacker can shove as much inline JavaScript as they want into your web application and it's just not going to run that said getting read of unsafe inline is particularly difficult for most organizations so let's take a look at a couple of real-life examples of how some companies have actually dealt with this so here's news.google.com and I want you to notice that they're using unsafe inline in addition to sending a nonce now Ananse has a very specific cryptographic term so if there's any cryptographers in the audience I apologize I'm sure I'm not gonna be 100% correct and encryption involves about
getting absolutely everything 100% correct thank you so much for your work but the short version is a nots is a random unguessable string of some sort and it needs to change every single time the page refreshes and the way this works is if the knots in the content security policy header is the same as the knots that's in the script tag it runs and if it's at all different content security policy shoots it in the head you see why this has to change every single time if you used a static non switch any cryptographer and the word just look at the word static nonce the attacker just drops that same string and it has to change every single time
and with modern browsers that understand the idea of knots it will then ignore the following unsafe inline part of the content security policy so this lets you fail open if you have a modern browser it's protected by the nonce if it doesn't understand what a nonce is the stuffs still gonna run you're not gonna break your site on older browsers another way that you can deal with unsafe inline is by hashing the script and putting that into the content security policy tab now I want to say that I got this exact example from Mozilla stocks and I really wanted to show this really cool bit of command-line foo of echoing it and piping it into sha-256 just the right
way to get the exact thing here and I couldn't figure this out so I'm sure Mozilla didn't get it wrong so my recommendation to you all is to do the same thing that I did is where you load it up into a browser and you have content security policy shoot it in the head and look at the console errors there'll be a really nice helpful thing where it says hey by the way if you want this to run just drop in this hash and yeah much better way to do that this is really similar to sub resource integrity if you're familiar with that where you specify the hash of third-party resources that you're embedding into
your site to say hey if this ever changes stop do not pass go do not collect $200 which by the way sub resource integrity you can mandate through content security policy anyway but to again go over this the they seem similar but they're different so just to recap a nonce is different every single time that you load the page and can never ever be the same and the hash is always the same and you update it anytime that you changed the script and both of these are ways to get inline javascript protected by your content security policy header all right with that let's take a look at another example which not just to bag on
Facebook but just to say as I said if you are at an organization and you just can't tighten the screws enough to get rid of unsafe inline in your content security policy header that's ok all right you're not if very very large companies with way way bigger application security budget still can't get rid of ends life inline and their content security policy know that you are in good company aim for that if you can but know that while it's technically simple it can often be really politically difficult to get an entire organization to clean up every single possible instance of inline running JavaScript and let's take another example of what it looks like in real
life here is Twitter that's crazy big so lots of times various people look at hopefully you get an idea of how specific you're able to get with this content security policy that you can tighten things down really really tight but in order to do that you need to have a complete guest list you need to know everybody that's coming to the party so oftentimes when I talk to various developers like this they say oh wow that looks really complicated I'm so glad that we have a security team that can think about this and at least in my experience that doesn't work particularly well I mean to put it another way the content security policy header the only reason that it
gets out of bed in the morning is to break stuff and to break stuff in production so the greater organizational distance your company has between the people writing the content and the people writing the content security policy header the more likely it is that it's gonna wake up one day and break something in production that we didn't want it to because the left hand didn't quite know what the right hand was doing so at least for me a couple of things that have worked well is well first off I think for as much as I love to have developers work on everything just politically there's always been some legacy application that was written by someone 17 years ago and no one
everybody wants to touch again to try to add a content security policy header for things like that the content on that side is probably not going to change too dynamically and just doing a bit of an audit and then tacking on that header using a proxy or a load balancer seems to work pretty decently well but for the rest of the things that you're doing with I again recommend to empower your developers to be able to know what a content security policy is and to be able to be authoring it I'd also recommend that you think really intentionally about whether or not you want your content security policy to fail open or to fail closed this is the
same with many other security tools where you get to decide depending on how you want to deal with things fail open or fail close could both be could a correct security decision but it depends on the context and the default source are going to this dip in the next slide the default source is where you decide whether or not your content security policy fails open or fails closed and the third thing that I recommend which we'll go over in a little bit again is use the report only header in order to figure out what's going to happen when you make a change or an edit to your content security policy so what do I mean about this fail open or fail close
imagine that there's a new type of content that we all want to be running on our site called fubar and so browser people get together and we're like great we're gonna add a fubar source directive to the content security policy and you're like great I use fubar in fact I use fubar from super food comm I'm just gonna go ahead and add that line into my content security policy what you have done is 100% correct a hundred percent to spec but the problem is that if you have an older browser that hasn't been updated to understand what the fubar source is it's just going to ignore that directive entirely and once it's ignored the directive entirely it's gonna fail back
to the default source so you can either say that your default source is none I've white listed every possible content that I want and if it's not on the list kick it out or set default source to star which will still protect your site for every single part every single directive that the browser understands it is restricted to the whitelist and then everything that it doesn't understand it just lets through again I'm not gonna tell Wii which of these two modes is correct for your application just know that you can write a 100% perfect 100% to spec perfectly exquisitely crafted content security policy and still break something in production you weren't meaning to not because of your fault that because
that's the ecosystem of browsers that we have to deal with and I just say the other thing that's worked really well and the places where I've tried to implement this is using the content security policy report only header which if you understand content security policy you understand the report only header you just tack those two words on at the end and it looks and acts and feels 99% the same as content security policy it just doesn't break anything and when it does that it'll still send you the report both the content security policy and the report only header will send this little JSON blurb that's very helpful tells you exactly where the thing was blocked what was blocked
what directive it violated that caused it to be blocked and lets you know what the policy it saw on that page was and the only part that's gonna be different is that disposition down at the bottom where either it's just gonna be reporting and we let this go through or says enforce where I took it out back and shot it in the head so that's content security policy again we're trying the sly do thing if the proctor wants to get up whatever questions that we have here at the time if there's not enough time for questions go ahead and get my contact information off there again go to this event in sched you can download the PDF of the slides and thank
you guys so much for your time that's what I got we have about three minutes for questions again go to slide oh and the code is b-sides FF 2019 they'll come up over here our first question is what about cores what about cores so cores is another header that you can be setting so if you're familiar with same origin policy this is basically a default in most browsers that restricts content for operating in the same kind of a same origin and this helps protect against cross-site request forgery where you go to attacker site and it tries to impersonate you on some other side core is is something that loosens the same origin policy it doesn't tighten it so I
don't necessarily it's related to security and so much that if you set it wrong it will you know help shoot yourself in the foot but it's not something that I find the default is more secure it please to my understanding do we have more questions um or are we out of time we have a little bit more time but no more questions well question in the room yeah you mentioned it's not all the browser's support this what about kind of browser like tools like curl or W get debase any of these so for things like curl or W get it it will show you the header that comes back but because it's not like executing JavaScript or loading images
it's not really something that it's looking at like it's gonna give you the the response that the tool gets back but isn't I don't know off the top of my head the types of attacks that you would do against curl except don't pipe it straight to bash but that the content security policy is not entirely applicable to command-line tools like that yep it's designed for kind of full-featured browsers again if I'm totally wrong you want to yell at me there's my contact information I'm gonna be hanging outside come say hi thanks you guys for the time so much all right on behalf of b-side San Francisco I'd like to thank you let's have a round of
applause for Benjamin