What it is: Improper Neutralization of Alternate XSS Syntax (CWE-87) is a type of cross-site scripting vulnerability where a filter blocks the standard script-tag syntax but misses other ways browsers can execute injected code.
Why it matters: Attackers maintain curated lists of every known alternate execution vector (CSS expressions, data: URIs, SVG handlers), so a filter tuned to only one syntax leaves many other doors open.
How to fix it: Use a maintained, actively-updated HTML sanitizer library instead of a custom blocklist of specific syntax patterns.
TL;DR: CWE-87 lets an attacker bypass an XSS filter using alternate script syntax the filter never anticipated (CSS expressions, data: URIs, SVG handlers); the fix is a maintained sanitizer library, not a custom pattern blocklist.
| Field | Value |
|---|---|
| CWE ID | CWE-87 |
| OWASP Category | Not directly mapped |
| CAPEC | CAPEC-199 |
| Typical Severity | High |
| Affected Technologies | Web applications, browsers |
| Detection Difficulty | Hard |
| Last Updated | 2026-07-27 |
What is XSS via Alternate Syntax?
Improper Neutralization of Alternate XSS Syntax (CWE-87) is a type of cross-site scripting vulnerability that occurs when a product does not neutralize user-controlled input for alternate script syntax. As defined by the MITRE Corporation under CWE-87, this weakness has no official OWASP Top 10:2025 category mapping but is a direct child of the broader Cross-site Scripting weakness (CWE-79).
Quick Summary
Browsers offer far more ways to execute script than a plain <script> tag — CSS expression() calls (historically in older IE), data: URIs carrying encoded script, SVG event-handler attributes, and other lesser-known vectors all achieve the same result. A filter built by testing against the obvious payload passes every manual test while still leaving these alternate doors wide open.
Jump to: Quick Summary · XSS via Alternate Syntax Overview · How XSS via Alternate Syntax Works · Business Impact of XSS via Alternate Syntax · XSS via Alternate Syntax Attack Scenario · How to Detect XSS via Alternate Syntax · How to Fix XSS via Alternate Syntax · Framework-Specific Fixes for XSS via Alternate Syntax · How to Ask AI to Check Your Code for XSS via Alternate Syntax · XSS via Alternate Syntax Best Practices Checklist · XSS via Alternate Syntax FAQ · Vulnerabilities Related to XSS via Alternate Syntax · References · Scan Your Own Site
XSS via Alternate Syntax Overview
What: A filter blocks the standard <script>-tag syntax but doesn’t account for other, less obvious ways a browser can execute injected code.
Why it matters: Attackers maintain curated lists of every known alternate vector, so a filter with a narrow blind spot is still fully exploitable.
Where it occurs: Any custom XSS filter or sanitizer built to block a specific, limited set of known patterns rather than using a comprehensive, maintained library.
Who is affected: Applications using hand-rolled filters or blocklists rather than actively-maintained HTML sanitization libraries.
Who is NOT affected: Applications using a well-maintained sanitizer library that’s kept current against newly discovered alternate syntax.
How XSS via Alternate Syntax Works
Root Cause
The application’s filter blocks a specific, known set of script-execution syntax but doesn’t account for other alternate vectors browsers support.
Attack Flow
- The attacker tests an application’s rich-content input against the standard
<script>payload and finds it’s blocked. - The attacker tries an alternate execution vector the filter didn’t anticipate — e.g. an SVG element with an
onloadhandler, or adata:URI carrying encoded script. - The filter, tuned to a narrower set of patterns, passes the alternate payload through.
- The browser executes the injected code via the alternate vector, achieving the same result as a blocked
<script>tag would have.
Prerequisites to Exploit
- The application’s filter blocks only a specific, limited set of known script-execution patterns.
- User input reaches a rendering context where the browser will interpret an alternate execution vector.
- The attacker knows or discovers a vector the filter doesn’t cover.
Vulnerable Code
import re
def sanitize(html):
return re.sub(r"<script.*?>.*?</script>", "", html, flags=re.DOTALL | re.IGNORECASE)
This filter only strips literal <script> tags, leaving every other execution vector (SVG onload, CSS expression(), data: URIs, and more) completely untouched.
Secure Code
import bleach
ALLOWED_TAGS = ["p", "b", "i", "a"]
ALLOWED_ATTRIBUTES = {"a": ["href"]}
def sanitize(html):
return bleach.clean(html, tags=ALLOWED_TAGS, attributes=ALLOWED_ATTRIBUTES, strip=True)
A maintained sanitizer library like bleach is built and updated specifically to account for the full range of known alternate syntax, rather than the narrow set one custom filter author happened to think of.
Business Impact of XSS via Alternate Syntax
Confidentiality: Attackers may read application data reachable from the victim’s session via an alternate-syntax injection.
Integrity: Attackers may perform actions as the victim through script executed via a filter’s blind spot.
Availability: Attackers may disrupt page functionality for the victim through the same bypass.
- Bypass of a filter that appeared thoroughly tested against the obvious payload
- Ongoing risk as new alternate execution vectors are discovered, if the filter isn’t actively maintained
XSS via Alternate Syntax Attack Scenario
- An attacker tests a comment feature’s HTML filter with a standard
<script>payload and finds it’s stripped. - They instead submit an SVG element containing an
onloadevent handler. - The filter, built only to strip
<script>tags, passes the SVG element through unmodified. - When the comment renders, the SVG’s
onloadhandler fires and executes the attacker’s script in the victim’s browser.
How to Detect XSS via Alternate Syntax
Manual Testing
- Identify custom HTML filters or sanitizers built as hand-rolled blocklists.
- Test with a broad range of alternate execution vectors (SVG handlers, CSS expressions, data: URIs, meta-refresh).
- Confirm whether any alternate vector executes despite the standard script-tag payload being blocked.
Automated Scanners (SAST / DAST)
Static analysis can flag custom sanitization logic implemented as a narrow regex/blocklist rather than a vetted library, while dynamic testing with a broad payload set confirms whether the live filter has exploitable blind spots.
PenScan Detection
PenScan’s scanner engines test XSS filters with a broad range of alternate script-execution syntax, not just the standard script-tag payload.
False Positive Guidance
If the application uses a well-maintained, actively-updated sanitizer library, most known alternate syntax should already be covered — confirm which specific vector, if any, actually executes before treating a general “custom filter” observation as a real finding.
How to Fix XSS via Alternate Syntax
- Use a maintained, actively-updated HTML sanitizer library instead of a custom blocklist.
- Resolve all input to its canonical representation before processing, to avoid encoding-based bypasses of any filter.
- Validate against a rigorous positive specification (allowlist) of permitted tags/attributes rather than blocking specific known-bad patterns.
Framework-Specific Fixes for XSS via Alternate Syntax
- Java: use the OWASP Java HTML Sanitizer with a defined allowlist policy, rather than custom regex filtering.
- Node.js: use DOMPurify (server-side via
jsdomor client-side) instead of hand-rolled tag stripping. - Python/Django: use
bleachwith an explicit allowlist, as shown above, rather than custom regex-based filtering. - PHP: use HTML Purifier with a defined allowlist configuration instead of custom blocklist filtering.
How to Ask AI to Check Your Code for XSS via Alternate Syntax
Review the following [language] code block for potential CWE-87 alternate-XSS-syntax vulnerabilities and rewrite it using a maintained HTML sanitizer library with an explicit allowlist instead of a custom blocklist filter: [paste code here]
XSS via Alternate Syntax Best Practices Checklist
✅ Use a maintained, actively-updated HTML sanitizer library ✅ Validate against a positive allowlist of permitted tags/attributes ✅ Resolve input to canonical form before processing to avoid encoding bypasses ✅ Test filters against a broad range of alternate execution vectors, not just script tags
XSS via Alternate Syntax FAQ
How does “alternate script syntax” bypass an XSS filter?
A filter tuned only to recognize “
How is this different from XSS in Attributes (CWE-83)?
CWE-83 covers a specific subset — event-handler attributes and javascript: URIs; CWE-87 is broader, covering any alternate syntax the filter didn’t anticipate, including CSS expressions, data URIs, and non-standard tag-based execution vectors.
How would an attacker discover a viable alternate syntax?
Attackers maintain and consult curated cheat sheets of every known browser-specific script-execution vector, then systematically try each one against a filter until one gets through untouched.
How do I detect this in my own application?
Test XSS filters against a broad set of alternate execution vectors (CSS expressions, data: URIs, SVG event handlers, meta-refresh redirects), not just the standard “
How do I fix this correctly?
Use a maintained, actively-updated HTML sanitizer library that already accounts for the full range of known alternate syntax, rather than maintaining a custom blocklist of specific vectors.
How does relying on a sanitizer library help more than a custom filter?
A vetted sanitizer library is updated as new bypass techniques are discovered across the whole security community, while a custom filter only accounts for the alternate syntaxes its original author happened to think of.
How can PenScan help find this weakness?
PenScan tests XSS filters with a broad range of alternate script-execution syntax, not just the standard script-tag payload, to find filters with narrow blind spots.
Vulnerabilities Related to XSS via Alternate Syntax
| CWE | Name | Relationship |
|---|---|---|
| CWE-79 | Improper Neutralization of Input During Web Page Generation (‘Cross-site Scripting’) | ChildOf |
References
Scan Your Own Site
Manual code review catches what you know to look for. An automated scan catches what you didn’t. Scan your own website using PenScan to find alternate-syntax XSS and other risks before an attacker does.