Yeah, so just letting you all know, I posted a copy of the slides on my Twitter, which is at KennySan. So if you want to follow along, you can just download a copy of the speaker deck straight from there. All right, let's begin. Hi, DEF CON. Yeah, so this is my talk, how to use content security policy to stop cross-site scripting. First a little bit of detail about myself. My name is Ken Lee. I'm a product security engineer at Etsy.com. In a previous life, I worked at a financial software company. As I just told you literally 30 seconds ago, my Twitter handle is at KennySan. If you have any questions, you can feel free to e‑mail me or send me a tweet. So let's talk about content security policy, because I assume that's the reason you're all sitting here today. The best way that I've heard content security policy described is it's essentially depth for the web. And by that I mean it is a way to tell ‑‑ for a server to tell your browser you're allowed to execute certain things and only these things that I tell you to execute. And by doing that, it provides for a mechanism to stop cross‑site scripting from happening. Just by a show of hands, how many people in this room know what cross‑site scripting is? Okay. Yep, all right. Then this slide is going to go extremely quickly. So as an example, I take, for example, a page, a page that's HTML, and I throw a very simple cross‑site scripting inside of it. This page has a content security policy on it, and if you look at the bottom of the page, the actual ‑‑ the execution of the script is blocked by the presence of a content security policy. And that's sort of basically how it works. Now for more detail, the way that it works is that a browser that is following a content security policy only follows a content security policy that is not a content security policy. It follows specific directives specified by the content security policy as elements that it's allowed to render or execute on the page. In particular, the two important things to note about this is that content security policy, by default, disallows the use of in‑line JavaScript on a page, which is a big thing that I will get to later. And in addition, it prevents the use of the eval style family of functions in JavaScript. So I'm just kind of throwing this up there. This is an example content security policy header. You know, you're not expected to understand this. There will be no quiz later on this. This is just to sort of demonstrate what a content security policy looks like. It's basically specified as a set of directives with a set of URIs and keywords that tells the browser what you are allowed to execute JavaScript and other elements from. So, content security policy, as I've said before, is broken up into a series of directives. The most common ones that you will probably end up using are directives such as script source which controls the use of JavaScript on a page, style source which controls the use of CSS and other styling on a page, and as you can see here, there's a directive for pretty much most types of things that you can embed on a web page. And in addition to that, there are also specific directives that you can embed on a web page. And in particular, there are special keywords that you can use in combination with the directives to modify your content security policy. So, for example, specifying a keyword of none for a script source directive tells the browser don't accept any source ‑‑ don't allow any JavaScript from any source. The self directive is pretty self‑explanatory. It basically says for ‑‑ only allow content from the same subdomain and scheme. And the unsafe inline and unsafe eval are special keywords that actually override the default functionality that I mentioned before with regards to content security policy blocking inline JavaScript and eval. So an important aspect of content security policy that I'm going to go into is the use of report only mode. Report only mode, basically, it's appended to the end of your content security policy header or content security policy meta-tag. And what this allows you to do is it allows ‑‑ it tells the browser, I want you to not ‑‑ I want you to not actually block elements that are disallowed by the content security policy. So it's essentially ‑‑ it's essentially a dry run. And what makes this functionality even more powerful is the use of a report URI. So at the end of your content security policy, you can actually specify a reporting end point which says ‑‑ which tells the browser, hey, you know, you've seen some bad shit with content security policy violations. Send those violations my way. And this basically provides a mechanism for the server to learn what kind of content security policy violations the server is seeing. And again, to emphasize, what's important about report only mode is that it doesn't actually block. You can deploy this without actually affecting content that the client is seeing. So an important aspect is that content security policy as a standard is still evolving. This little snippet of a screenshot was taken from a version of Firefox not too long ago. And it's hard to read the text. What it basically says is CSP warn failed to parse unrecognized directive unsafe inline. Firefox at the time that the screenshot was taken had a bug where it didn't recognize the unsafe inline or unsafe eval directive. And I think the latest version of Firefox, Firefox 23, actually had a bug where it didn't recognize the unsafe inline and it still has a bug where it doesn't allow you to whitelist unsafe style source elements. So like I said, browsers these days are mostly up to spec with regards to CSP 1.0 compliance. But if you happen to notice in the process of your testing for content security policy that you're seeing some unexpected behavior, there is a strong possibility that it may not necessarily be your content security policy. It could just be the client's browser. And you're acting like a smelly lobster. So let's talk a little bit more in detail about the inline JavaScript bit that I alluded to earlier. So as I mentioned, content security policy 1.0, this allows by default the use of inline JavaScript on a page. This is actually, as it turns out, kind of a big deal. The way that is recommended to sort of deal with inline JavaScript is to create external scripts out of all your inline JavaScript. This has kind of a number of implications. The biggest one being that you're essentially turning all these inline bits of JavaScript into synchronous calls that the browser has to retrieve the JavaScript from. Alternatively, if you want to get around this, you can also specify, as I mentioned before, the unsafe inline directive. But this has implications for defeating or basically weakening the strength of your content security policy. And in addition, if you use any kind of asynchronous JavaScriptiye.com. JavaScript loading libraries such as RequireJS, this also has implications as well because RequireJS and other asynchronous JavaScript loading libraries, what they like to do is they essentially like to say, hey, I want to load this bit of JavaScript, so at some point during the rendering of the page, I'm going to basically call append child to the head of the document with the contents of the JavaScript. And because this is all done asynchronously, it's very fast. There's no additional HTTP call, but the problem is that that's going to cause issues with content security policy 1.0. So as a result, you know, there are potential performance implications to deploying CSP 1.0 by turning all of your scripts into externalized bits of JavaScript. Hopefully content security policy 1.1 will fix that, as right now they're sort of working out the final bits of the spec, but they will essentially be a way to safely whitelist inline JavaScript on the page. So let me talk about some real world implications about deploying a content security policy to your production website. So, oh, my God, this is terrible. So there's a couple questions that a lot of you probably have if you want to ‑‑ if you think about rolling out a content security policy to your web site. For example, how should you go about rolling out a content security policy to your web site? How should you test the validity of your content security policy? And what bits should you throw the content security policy on to? A number of websites such as Twitter, for example, have chosen to focus their content security policy on specific segments of their website. And this actually makes a lot of sense from a metric standpoint because it's It gives you a very focused approach to applying and fixing the issues that your content security policy detects. So these are two just graphs of Splunk showing a hit count of content security policy violations that have been sent from client browsers using the report only directive to an end point that I've specified. And, in addition, this ‑‑ the bottom graph shows a list of top blocked URIs. So what's really powerful about content security policy is that if you specify a report only end point, you can use this to essentially learn all the things about ‑‑ about content security policy violations that clients are seeing. And this potentially has some really interesting implications. In the process of looking into content security ‑‑ content security policy violations, during the evolution of the spec, one of the things I noticed was the fact that you end up seeing a lot of mixed content on your website. And the nice thing about content security policy is that it's actually really effective at helping you root out and stamp out all those instances of mixed content on your website. So essentially the technique that one can use for detecting this mixed content on your website is... If you specify a content security policy violation, you're going to get a lot of mixed content policy and you have a reporting endpoint, if you see the reporting endpoint, the browser essentially sends a JSON blob to the reporting endpoint containing information such as the document URI, the URI of the block element, what have you. And so basically if you just parse this blob and detect if the scheme of the document scheme that was retrieved was HTTPS and the block URI was HTTP, then you have an instance of mixed content sitting on your website. Granted, certain headers such as HTTP strict transport security can actually be an effective approach in essentially removing mixed content from your website because this will force all your subdomains to HTTPS. But from an implementation standpoint, from experience, I've discovered that most of the issues that you will run into. With mixed content on your website when rolling out a content security policy won't be from your own subdomain. Surprise, surprise. It will actually be coming from, in most instances, third party vendors who don't, for example, simply don't have an HTTPS endpoint for their website. So a couple thoughts, additional thoughts about content security policy. As I mentioned before, unsafe inline and unsafe eval. Essentially. It will actually severely nerf the protective abilities that content security policy give to you. So it's important when deploying a content security policy to consider whether or not you should include these directives in your policy. In addition, content security policy, if you choose to implement it as a header, you can potentially be including a very, very large number of sources in your policy. And that can cause your header sizes to grow. Which can potentially have. An impact on performance. And the final last sort of obvious point is that you should always make an effort to test your content security policy before you roll out to production. So let me get to the final good bits before talking about the tool that I created. So if you want to test content security policy right now, live, it's a thing that exists in Firefox 23 and Chrome 25. Previous versions of this browser used, I believe, the X content security policy. It's a thing that exists in Firefox 23 and Chrome 25. Previous versions of this browser used, I believe, the X content security policy. It's a thing that exists in Firefox 23 and Chrome 25. Previous versions of this browser used, I believe, the X content security policy. It's a thing that exists in Firefox 23 and Chrome 25. And if you want, you can test this out. You can apply the report only header or as a meta tag to simply have the browser attempt to basically not block instances of bad JavaScript or style elements that it sees. In addition, the report is tremendously powerful from a metrics perspective. just because of the fact that it can give you so much information on what clients are actually potentially seeing in terms of blocked content. And with the ability to monitor all of this blocked content via either Splunk or StatsD or Graphite or some other logging metrics tool that you use, it gives you the ability to look into and fix all of your in-line JavaScript issues that are caused by deploying a content security policy. All right. So let me talk a little bit more in depth about the tool that I'm releasing. So one problem that I initially ran into when deploying a content security policy was that it was actually really annoying to test my content security policy in a development environment and then push it to production because of the very nature of the fact that in production I would have to specify prod hosts and in dev, you know, I would have to use dev hosts. And it was annoying to the point where I didn't want to have to constantly poison my host host file to have to handle this. So I decided, you know, F it. I'm going to make some tools to help me fix this problem. So CSP tools is essentially a set of three Python‑based tools that do the following. The proxy tool is essentially a Python proxy written using libm proxy that intercepts all HTTP and HTTPS traffic. And what it will do if you connect to this proxy is it will insert ‑‑ dynamically insert a kind of content security policy report‑only header with the policy you've specified. In addition, the proxy will also capture any content security policy violations the browser sends back to the proxy end point. The browser tool is basically a Selenium‑powered instance of Firefox. And what that does is it essentially allows you to create unit tests for content security policies that you've deployed to specific pages on your website. And finally, the parser tool, which is fairly self‑explanatory, what that does is it takes ‑‑ MR. Excuse me. MR. So have you attended any talks? MR. Yeah, in past DEF CONs, yes. MR. Okay. So we're here to actually help you out. This is your first time speaking, right? MR. Yeah. MR. How's he doing? MR. We have a little ‑‑ as many of you know, we have a little tradition here, as our speaker does not seem to know, where all first‑time speakers must do shots. We also have some other first‑time ‑‑ MR. Yeah. MR. Attendees to DEF CON. MR. There you are. MR. Thank you, sir. MR. All right. Congratulations. MR. Cheers. MR. Cheers. MR. Oh, my gosh. MR. Wait a second. MR. And where's Heather? It's Heather. Heather, raise your hand. Yep. It's Heather's first time at DEF CON 2. MR. Woo! MR. Come on. Give it up for Heather. MR. Woo! MR. All good. MR. All good. MR. And now back to our regularly scheduled ‑‑ oh, shit, your time's up. MR. Damn. MR. Damn it. MR. Sorry, folks, no demo. MR. Just kidding. MR. So here's a little demo of the CSP proxy at work. I'm browsing to this one website, www.etc.com. You may have heard of it before. Wow, that really hit me hard. MR. So I'm just going to the console to demonstrate, you know, there's no tricks up my sleeve, no content security policy here. Going to the network tab, just showing you that the get request does not actually have a content security policy specified in the response. So scrolling back down, you can see no tricks here. So in a second, when this really slow video demo finishes, I'm going to change my proxy settings for Chrome to specify using a proxy on local host port 8080. If I'm talking a little slower, it's because I just had a lot of alcohol. MR. And now more alcohol. MR. Woo! MR. Yeah. So I'm starting up the proxy. I'm specifying a host of www.etc.com. And now I'm going to reload the page now that the browser is using this proxy. And you can see here from loading the page, it's seeing some content security policy violations. If you look at the initial get request, we can see that a content security policy report only header is in the first response from the server. And if we ‑‑ and we can see here a content security policy violation being sent back. to the proxy. And in addition we have a number of content security policy violations being logged on the console. So that's essentially how the proxy tool works. And if you actually look into the log file that's generated by the proxy, all it is, like I said before, no lies, I wouldn't do that to you guys, is just simply JSON blobs of the content security policy violations that the proxy has logged to disk. All right. So now this next video is demoing the parser and browser tool. I'm going to load up the proxy again, this time on port 8090, and I'm going to fire off the Selenium powered browser tool. And I've specified a number of URIs, specifically five, a number of HTTP and HTTPS links for the browser to log to. And since I've specified my proxy on port 8090 for the browser to use, it's going to log to the browser. So I'm going to connect directly to the proxy and send, as you can see in the background, send content security policy violations directly to the proxy. So you can see here I'm browsing a couple of URIs, first the front page of Etsy, now some HTTPS link, which it loads just fine. And you can tell the proxy is chugging away happily because it basically just logs all content security policy violations right off the bat. And I'm going to jump ahead. So I implemented this using basically Selenium. And if you really wanted to, you could actually modify this to make the whole thing run headless so you don't actually have to see the browser running. So now we've closed down the proxy after the browser is done running. We're going to look at our CSP violations. We can see we have a ton of them. And they've hit the URIs that we've specified, which is excellent. So now we can go about the process of making a content security policy violation ‑‑ content security policy using the parsing tool. And, bam! We've just created a content security policy for our Web site. So yeah, if you want to get CSP tools, it's available on GitHub at the following URL. Feel free to issue pull requests if you find bugs with my implementation. Also, if you have questions, by all means, hit me up afterwards in the QA lounge or on Twitter, which is, again, Kenny Sonn, if you want to view a copy of these slides. I would also like to give a huge shout out to Kai Zong for helping me tremendously with the initial implementation of CSP and also just a general shout out the easy security team for being tremendously supportive of my efforts in implementing content security policy. Oh, my God. Okay. JAVIER OTERO REESE? RAFAEL SANCHEZ? RAFAEL SANCHEZ? RAFAEL SANCHEZ? Oh, my God. You guys are the worst. I mean the best. So, yeah, again, if you want to ask questions, the QA lounge outside is the appropriate place to be asking them, at least from what I've been told. So thank you.