Secure Legion Labs

Stored XSS Lab

Stored XSS

This lab simulates a comment system that stores user-supplied content and renders it later. The goal is to understand persistence, second-view execution, and why stored XSS is often more dangerous than reflected issues.

ObjectivePersist a payloadStore content that becomes dangerous when the page renders it.
DifficultyIntermediatePersistence adds a more realistic attack path.
FlagUnlock on solveThe flag appears after the lab detects the stored execution path.
Comment Workflow

How the payload enters the app

  • InputComment submission
  • StoragelocalStorage comment store
  • RenderinnerHTML comment list
Hint: The important question is not what the form accepts immediately. It is what happens when saved content is trusted and rendered again later.
Filter Logic

What the page tries to block

The page applies a weak string filter before storing the comment. That can block some obvious cases while still leaving practical payload paths for an attacker.

replace(/script/gi, "")
replace(/alert/gi, "blocked")
Submission Console

Store a payload

Submit a comment, refresh the page, and observe how the stored content is rendered again.

Storage key: secureLegionStoredXssComments
Stored comments preview
Persistent Render

Comments Feed

The feed below renders stored comments through innerHTML, which simulates a stored XSS execution point.

No comments stored.

Status: waiting for stored input.

Flag Unlock

Challenge flag

The flag appears after the stored payload path is recognized.

Flag:
Submit Flag

Validate completion

Submit the unlocked flag to complete the stored XSS room.

Flag is locked until you trigger the challenge condition.

Execution Path

How stored XSS happens here

1. Submit payload

The attacker stores content through the comment form.

2. Persist data

The app saves the result and treats it as trusted later.

3. Render later

When the feed loads again, the stored HTML reaches the sink.