帳
XSS Dojo · v2.0 — 帳
帳への挑戦 Enter the Ledger
A company invoice generator has 11 input fields. The developer secured most of them — but one field uses a different sanitizer. Find it, exploit it, and execute alert(document.domain) to claim your katana.
⛩ Read the source carefully. Not every field is equal.
The Sanitizer Source — Read carefully. Not every field is equal.
invoice.php — field processing & rendering (real source)
// ── Invoice Generator — Field Processing ──────────
// Standard fields (all use htmlspecialchars)
$company = htmlspecialchars($_GET['company']);
$regNo = htmlspecialchars($_GET['reg_no']);
$billAddr = htmlspecialchars($_GET['bill_addr']);
$client = htmlspecialchars($_GET['client']);
$email = htmlspecialchars($_GET['email']);
$item = htmlspecialchars($_GET['item']);
$qty = (int)$_GET['qty'];
$price = preg_replace('/[^0-9.,]/', '', $_GET['price']);
$notes = htmlspecialchars($_GET['notes']);
$issuedBy = htmlspecialchars($_GET['issued_by']);
// ── "Handle" — rich-text for display badges ───────
// Allows formatting like:
// "<b>@TeamRed</b> <em>solo_hunter</em>"
###### = $_GET['samurai_0x']; // ← no htmlspecialchars
// Gate 1 — Allow only "safe" formatting tags
##### = strip_tags(samurai_0x,
'<b><i><u><em><strong><br><a><span><p>'
. '<ul><ol><li><details><summary>'
. '<hr><blockquote><code>'
);
// Gate 2 — Strip event handlers (double-quoted)
dsfghsdfhfdsh = preg_replace(
'/\s+on[a-z]+\s*=\s*"[^"]*"/i', '', ghsdf54hg
);
// Gate 3 — Strip event handlers (single-quoted)
dsagsdg = preg_replace(
"/\s+on[a-z]+\s*=\s*'[^']*'/i", '', ######
);
// Gate 4 — Block dangerous URI schemes
fhdfhfdh = preg_replace(
'/(href|src|action)\s*=\s*["\']?\s*(javascript|data|vbscript)\s*:/i',
'$1="blocked:', #######
);
// Gate 5 — Block dangerous function calls
###### = preg_replace(
'/\b(alert|confirm|prompt|eval|Function
|setTimeout|setInterval)\s*\(/i',
'', #####
);
// Gate 6 — Length limit
###### = substr(#####, 0, 600);
?>
// ── Rendering ─────────────────────────────────────
// Safe fields → textContent (no HTML interpretation)
el('inv-company').textContent = "<?= $company ?>";
el('inv-client').textContent = "<?= $client ?>";
el('inv-notes').textContent = "<?= $notes ?>";
el('inv-issued').textContent = "<?= $issuedBy ?>";
// ... all other fields use textContent
Invoice Generator — 11 fields, 1 sink
Company Details
Client & Line Item
Notes & Signature
⏱ Wait 5s
✗
/ filter output /
⚠ Text-only preview. Use "Generate Invoice" for live rendering.
帳簿突破 — Ledger Breached
alert(document.domain) fired. Claim your katana.
Rules of Engagement
Goal
Execute
alert(document.domain) — find the right field first11 Fields
10 use
htmlspecialchars → textContent. Only 1 uses the filter chain → innerHTML.Two Modes
"Test Field" shows filtered output per field. "Generate Invoice" renders the real preview.
No Automated Fuzzing
Manual payload crafting only. Read the source, think, don't bruteforce.
Hall of Fame
侍の道 — Path of the Samurai
Resets with each new challenge
一
maasi_no_tamburoo
2026-02-26
⚔
二
0xnay33m
2026-02-28
⚔