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.

Difficulty: ◆◆◆◆ Extreme
⛩ 2 Samurai have claimed victory
11 Fields · 1 Sink · 6 Gates
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
                
⏱ Wait 5s
/ filter output /
⚠ Text-only preview. Use "Generate Invoice" for live rendering.
帳簿突破 — Ledger Breached
alert(document.domain) fired. Claim your katana.
Goal
Execute alert(document.domain) — find the right field first
11 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.
侍の道 — Path of the Samurai

Resets with each new challenge

maasi_no_tamburoo
2026-02-26
0xnay33m
2026-02-28