Listen to this Post

Introduction:
Cross-Site Scripting (XSS) remains one of the most pervasive vulnerabilities in web applications, primarily mitigated by filters that block malicious characters like <, >, and quotes. However, security professionals often overlook a critical nuance: the Unicode normalization process. When a Web Application Firewall (WAF) inspects traffic, it sees encoded bytes; but if the backend application normalizes Unicode after the security layer, attackers can use fullwidth variants of standard characters to slip malicious payloads past the filter, only to have them transformed into valid HTML tags during rendering.
Learning Objectives:
- Understand the mechanics of Unicode normalization and how it creates a gap between WAF inspection and application parsing.
- Learn to identify and exploit Unicode fullwidth character variants to bypass XSS filters.
- Implement defensive coding practices and normalization strategies to mitigate these advanced bypass techniques.
You Should Know:
1. Exploiting Unicode Fullwidth Variants for XSS
The core of this bypass relies on the existence of “fullwidth” Unicode characters that visually resemble their ASCII counterparts. In the provided post, the researcher highlights specific URL-encoded variants:
– `<` becomes `%EF%BC%9C` (Fullwidth Less-Than Sign)
- `>` becomes `%EF%BC%9E` (Fullwidth Greater-Than Sign)
– `”` becomes `%EF%BC%A2` (Fullwidth Quotation Mark)
– `’` becomes `%EF%BC%87` (Fullwidth Apostrophe)
– ` becomes `%EF%BD%80` (Fullwidth Grave Accent)
When a WAF scans a request, it typically looks for the literal `<` character or its standard URL-encoded form %3C. It does not inherently recognize `%EF%BC%9C` as a threat because it is a different byte sequence. However, if the application or database normalizes this Unicode string to its ASCII equivalent after the WAF check, the payload becomes executable.
Step‑by‑step guide explaining what this does and how to use it:
To test this vulnerability manually using browser developer tools or a proxy like Burp Suite, follow these steps:
- Identify a Reflection Point: Find an input field or URL parameter where user input is reflected in the DOM (e.g., a search bar, comment section).
- Test Standard Payload: Send a standard test payload like `` to confirm the WAF is filtering it (you should see a 403 block or the tags being stripped).
- Encode to Fullwidth: Replace the filtered characters with their Unicode fullwidth equivalents. For example, change `