
跨站脚本攻击(XSS)是指攻击者将恶意脚本注入Web页面,当用户访问该页面时,浏览器执行恶意脚本,窃取用户数据或执行恶意操作,核心是用户输入被当作脚本代码执行,导致脚本在用户浏览器中运行。
XSS的原理是用户输入未被正确处理,直接嵌入页面输出。具体来说,当用户在表单、URL参数等位置输入恶意内容(如<script>alert('hacked')</script>),若服务器未对输入进行过滤或转义,页面渲染时浏览器会解析并执行这段脚本,从而实现攻击。类比:把网页看作一个“浏览器容器”,正常用户输入是“安全食材”,服务器处理时应该“烹饪”(过滤/编码),但若直接“生吃”(原样输出),恶意输入(如毒药)就会导致用户“中毒”(脚本执行)。
不同类型XSS的对比(定义、特性、典型场景、防御重点):
| 类型 | 定义 | 特性 | 典型场景 | 防御重点 |
|---|---|---|---|---|
| 反射型 | 恶意脚本通过URL参数传入,页面返回时直接显示 | 脚本随请求返回,不存储在服务器 | 用户点击恶意链接(如广告、搜索结果) | 输入验证(检查URL参数是否包含脚本标签)、输出编码(HTML转义) |
| 存储型 | 恶意脚本存储在数据库等持久化存储中,用户访问时加载 | 脚本存储在服务器端,多次访问触发 | 用户评论、用户资料页、论坛帖子 | 输入过滤(白名单,仅允许安全字符)、存储编码(数据库转义)、访问控制(用户权限) |
| DOM型 | 脚本在客户端执行,通过DOM操作获取数据(如URL参数、DOM元素内容) | 脚本在浏览器端执行,不涉及服务器 | 用户点击链接后,脚本从URL或DOM获取数据并执行 | 输出编码(客户端JavaScript转义,如HTML实体编码)、DOM安全策略(禁用eval、innerHTML等危险操作) |
反射型XSS示例:
用户输入<img src=x onerror=alert(1)>,服务器未处理,页面显示时,浏览器执行onerror事件,弹出alert。
请求示例:GET /search?query=<img src=x onerror=alert(1)>,服务器返回页面包含该脚本,浏览器执行。
存储型XSS示例:
用户在评论框输入<script>alert('用户评论中的脚本')</script>,服务器存入数据库,其他用户访问评论时,页面渲染时执行脚本。
DOM型XSS示例:
用户点击链接/xss?data=<script>alert(1)</script>,客户端JavaScript获取URL参数data并执行,浏览器执行脚本。
(约90秒,自然表达)
“XSS是用户输入被当作脚本执行,导致恶意代码运行。原理是服务器未正确处理用户输入,直接嵌入页面。防御方法包括:输入验证(检查输入是否包含脚本标签,如<script>或javascript:,用正则过滤,但需注意正则可能漏掉编码绕过)、输出编码(将HTML特殊字符转义,如<→<、>→>,不同上下文编码规则不同,如HTML、JavaScript、CSS需分别编码)、内容安全策略(CSP,通过HTTP头如Content-Security-Policy: script-src 'self';限制脚本来源,阻止加载外部恶意脚本)。反射型XSS用户输入随URL参数带过来,页面返回时直接显示;存储型则是输入存数据库,用户访问时加载。CSP通过指定允许的来源,防止加载恶意脚本。总结:输入端过滤、输出端编码,配合CSP提升安全性,其中输入验证是基础,输出编码是关键,DOM型需额外用客户端编码和DOM安全策略。”
问:不同类型XSS的区别?
答:反射型(脚本随请求返回,不存储)、存储型(脚本存储在服务器,多次访问触发)、DOM型(客户端执行,通过DOM操作获取数据)。
问:CSP的作用?具体配置示例?
答:CSP限制页面加载资源,防止执行外部脚本。示例:Content-Security-Policy: script-src 'self';,作用是只允许同源脚本,阻止外部恶意脚本。
问:输入验证和输出编码哪个更重要?
答:输入验证是基础(防止恶意输入进入系统),输出编码是关键(防止已进入系统的输入被执行),两者结合。
问:DOM型XSS如何防御?
答:客户端输出编码(如JavaScript转义HTML字符,如document.write(encodeURIComponent(data)))、DOM安全策略(禁用eval、innerHTML等危险DOM操作,改用textContent)。
问:如何检测XSS?工具的局限性?
答:检测方法包括手动测试(输入特殊字符)、工具(如Burp Suite、WAS)、自动化扫描。局限性:WAF可能误报(正常脚本被拦截)、漏报(复杂XSS攻击),且CSP绕过(如data URI)可能检测不到。
<script>),或使用黑名单过滤,可能被编码绕过(如<script>alert(1)</script>变成<script>alert(1)</script>)。