pwneglyph logo
web javascript idna unicode csp-injection xss normalization

Use fullwidth punctuation that IDNA normalization collapses into ASCII syntax inside a CSP header or inline JS string.

IDNA / Fullwidth Unicode → CSP Injection + JS Breakout

IDNA normalization can collapse fullwidth punctuation into ASCII punctuation after validation. A string that looked harmless to one layer becomes syntax to another. When the normalized value is placed inside a CSP header or inline JS string, one normalization step can become both a header injection and a JS breakout.

Why It Works

  • Validation happens before normalization; afterward, fullwidth /"/< become real syntax in the sink context.

Vulnerable Pattern

  • Hostnames normalized through IDNA and then embedded into security-sensitive text contexts: CSP directives, JS config blobs, or HTML attributes.

Exploit Flow

  1. Identify exactly where the normalized hostname lands: header, JS string, HTML attribute, or URL.
  2. Choose fullwidth punctuation that becomes the syntax you need after normalization.
  3. Confirm the header or string breaks structurally before aiming for final XSS.

Variations

  • Fullwidth semicolon for CSP directive separators, fullwidth quotes for string termination, and angle brackets for HTML breakout.

Common Blockers

  • Strict hostname validation before IDNA, or the normalized string never reaching an active context.

PoC Sketch

# hostname with fullwidth punctuation that, after IDNA, becomes:
safe.example;script-src 'unsafe-inline';x="<script>console.log(document.cookie)</script>"

Good Situations To Use It

  • A hostname is IDNA-normalized then reflected into CSP/JS/HTML.
  • Validation runs before normalization.
  • The sink context is syntax-sensitive.

Sources

  • midnight_flag2026/web/forbidden_script_ritual