Security conferences often have hacking challenges. My colleagues and I have built a number of these. We've not yet done one that includes a cross-site scripting vulnerability.

I have seen challenges that do this. One approach was that a certain page (vulnerable to stored XSS) was requested by a browser on a periodic basis (every 10s I think). After successful attack, your payload ran in that browser and the challenge was to extract the cookie.

One issue with this approach is that when multiple people are working on the challenge simultaneously, they interfere with each other - and you can steal other people's ideas. An alternative idea was to have reflective XSS only, and a page where you can submit a link to the site, which admin will review before it goes live.

How long to have the browser stay open is an interesting choice. If it stays open a while (60s or so) then people can use tools like BeEF, which makes it a bit easier. If it's only open for 2s you have to script the attack.

There's a number of details that affect how well the challenge will work in practice. I'd prefer answers from people with experience running XSS hacking challenges that worked well. But failing that, I'll settle for informed speculation.

If it helps, we tend to attend technical conferences in the UK, e.g. B-Sides Manchester, SteelCon, SecuriTay.

Also, any hints about defending the browser from JavaScript exploits would be welcome!

  • 1
    Here's a good example: xss-game.appspot.com Dec 22, 2016 at 18:48
  • @AndrewKoroluk - Interesting site, thanks for that. I think it works by emulating a browser in JavaScript? While that's fine for learning XSS, I worry it wouldn't be a fair environment for people doing advanced stuff
    – paj28
    Dec 22, 2016 at 18:58
  • AFAIK it's all client-side. I believe it emulates having a browser inside an IFrame, and uses the postMessage API to determine whether the alert function gets called. Dec 22, 2016 at 19:04

4 Answers 4


The most common approach I've seen is to run a headless browser bot that gets vulnerable links through a submission system. It then visits each of these links for a few seconds with a magic cookie set.

An example can be found in the article "How to add an XSS-able bot to your CTF" where the bot is implemented as a headless PhantomJS instance. Similarly, the hackxor game uses HtmlUnit to simulate a browsing victim and this XSS challenge uses an instance of Zombie.js.

There are indeed several reasons to avoid stored XSS: Not only would players learn about the others' methods and eventually interfere with their payloads but people might start annoying others with redirects or infinite loops which will keep you busy with cleaning everything up.

Instead I'd suggest a reflected XSS vulnerability with a simple submission system where players can provide links that are then visited by the bot. Depending on the scenario, the submission could be put in the context of a contact form, a simple socket listener, a private IRC message, or, if you feel fancy, an email account where the links from incoming emails are extracted and visited.

I'd definitely avoid a system that requires manual interaction. Otherwise people will constantly inquire if their payloads have already run, if it can be visited again, etc. Depending on how aggressive the players are you should also think of a way to rate-limit submissions. (A CAPTCHA for the contact form would fit the scenario well.)


I would recommend individual container environments to separate conflicts between contestants.

For an example: Check out SANS’s one hour CTF at https://www.onehourctf.com – The One-Hour CtF uses Docker and Guacamole to provide a snappy shared learning environment. Guacamole provides the visual (VNC/RDP/SSH) interface to the Docker containers.

For an easy method for teaching cross-site scripting vulnerabilities, you may want to consider an educated simulation of the attack with custom code. From the attackers perceptive it's legit, but the back-end simulates the visual results.

  • 1
    Nice idea about spinning up containers. I'd like to avoid that if possible - I expect there's a fair bit of overhead with it. This is NOT an easy method of teaching vulnerabilities, it is a hacking challenge (CTF) and I would not feel comfortable using anything emulated, it wouldn't be a fair environemtn.
    – paj28
    Dec 22, 2016 at 17:05
  • Figured i'd throw the ideas out there =) best of luck! I run cyphercon.com , would love to hear what you come up with at the end!
    – Kamic
    Dec 22, 2016 at 17:22

It's clearly great to narrow down with systematic approach of developing the CTF's. This could be done via knowledge repositories which contains similar attack vector.

For an example, in your CTF's - you intend to focus on code injections - the variants related to code injection attacks are absolutely related to client side scripting exploitation. To narrow it down, use the key ingredient feature which's abused. In this particular case, mostly JavaScript and it's JS Engines are vulnerable. Hence, your team should be able to collate information regarding this say JS Vuln DB can fetch you CVE's + it's POC to start from!

Let's take yet another scenario. Say you're to make CTF's which's intended towards 'File Includes` vectors, examples could be LFI, RFI, SSI, etc.. you could use API provided by cve-search & then possibly map all CVE's down so it's easier.

Idea is to centralise & yet isolate practice run in the secure environment if you're to blue team. Secondly, I suggest maybe, a fine tune or a buffer additional context based exploitation could work out after having twisted the originals. That's where you start from. The first problem of having cookie ideas stolen, you can easily have it rectified via using different parallel sandboxes. I guess there are providers which have this kind of a set-up. Check out CTF365.

  • 1
    This is useful info on CTFs in general. But it doesn't address my immediate question. In particular, I'm talking about using an XSS vulnerability to extract cookies from a user's browser. I'm NOT suggesting directly targeting the browser, breaking out of the sandbox.
    – paj28
    Dec 22, 2016 at 17:09

If all you need is for your server to visit a given url, then rather than having bots and threads spinning up etc. the simplest solution would be to immediately (as soon as the url is submitted) visit the url using a library (like requests in python) that allows to parse the response as well. As if an admin or some other bot had visited it for real, in their own browsers.


Here follows a more detailed explanation (as requested). As soon as the user input is received (in this case, e.g., a url), just pass it to the following function:

def simulate_admin_visits(url):
    #initialise with empty cookies
    jar = requests.cookies.RequestsCookieJar()
    #visit the page that allows the admin to login 
    #and collect the cookies from the response
    response = requests.post(LOGIN_URL, data={'uname': ADMIN_UNAME, 'password': ADMIN_PASSWORD}, cookies=jar)
    #visit the user-submitted content using the just-collected cookies
    #here the exploit/ctf_challenge-solution is allowed to work
    <parse the submitted content>
    #have the admin logout
    requests.get(LOGOUT_URL, cookies=jar)
except ConnectionError:
    print 'Could not connect to ' + url

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .