一、什么是 XSS 攻击?
1.1 定义
XSS(Cross-Site Scripting,跨站脚本攻击)
攻击者通过在目标网站注入恶意 JavaScript 脚本,当用户访问时,脚本在用户浏览器中执行,可实现:
- 窃取 Cookie / Session
- 伪造用户操作(如转账)
- 钓鱼页面重定向
- 篡改页面内容
1.2 核心原理
用户输入 → 未过滤/转义 → 浏览器解析执行 → 攻击成功
1.3 XSS 攻击的三种类型
| 类型 | 特点 | 攻击场景 |
|---|---|---|
| 存储型 XSS(持久化) | 脚本存储到服务器(数据库、文件) | 论坛评论、用户资料、商品评价 |
| 反射型 XSS(非持久化) | 脚本通过 URL/表单 传入,服务器直接返回 | 搜索结果、错误提示、登录失败页面 |
| DOM 型 XSS | 纯前端,通过修改 DOM 触发 | innerHTML、eval、location.hash 等 |
二、Java 代码实践 XSS 攻击(完整可运行)
2.1 环境准备
1 |
|
2.2 反射型 XSS 攻击实践
2.2.1 存在漏洞的代码(未防御)
1 |
|
2.2.2 攻击演示
- 启动应用,访问:
1 | http://localhost:8080/search?keyword=<script>alert('XSS')</script> |
浏览器弹出弹窗,说明脚本执行成功。
窃取 Cookie 攻击:
1 | http://localhost:8080/search?keyword=<script> |
攻击者可获取用户登录凭证!
2.3 存储型 XSS 攻击实践
2.3.1 存在漏洞的代码(未防御)
1 |
|
2.3.2 攻击演示
- 使用 PostMan 发送 POST 请求:
1 | POST http://localhost:8080/comment |
- 访问
http://localhost:8080/getComments
→ 所有访问该页面的用户都会弹出弹窗!
2.4 DOM 型 XSS 攻击实践
2.4.1 前端页面(存在漏洞)
1 |
|
2.4.2 攻击演示
- 访问
http://localhost:8080/dom-xss.html - 输入:
1 | <script>alert('DOM XSS!')</script> |
- 点击提交 → 弹窗触发(无需服务器参与)
三、XSS 攻击的防御方法(实战代码)
3.1 输入验证(白名单过滤)
1 | public class InputValidator { |
控制器中使用
1 |
|
3.2 输出转义(核心防御)
1 | public class HtmlUtils { |
控制器中使用(修复反射型)
1 |
|
修复存储型输出
1 | sb.append("<li>").append(HtmlUtils.htmlEscape(c)).append("</li>"); |
3.3 安全前端渲染(防 DOM 型 XSS)
1 | // 修复后:使用 textContent |
永远不要用
innerHTML渲染用户输入!
3.4 设置 CSP 响应头
1 |
|
3.5 设置 HttpOnly Cookie
1 |
|
3.6 使用 OWASP Java Encoder(推荐)
添加依赖
1 | <dependency> |
使用
1 | import org.owasp.encoder.Encode; |
四、防御总结表
| 防御手段 | 适用场景 | 优先级 |
|---|---|---|
| 输出转义 | 所有渲染到 HTML | ★★★★★ |
| 输入验证 | 格式固定输入 | ★★★★ |
| CSP 头 | 全局脚本控制 | ★★★★ |
| HttpOnly Cookie | 保护凭证 | ★★★★ |
| textContent 渲染 | DOM 操作 | ★★★★ |
| OWASP Encoder | 复杂项目 | ★★★ |
五、注意事项
- 组合防御:输入验证 + 输出转义 + CSP
- 富文本场景:使用 OWASP AntiSamy 白名单过滤
- 定期扫描:使用 OWASP ZAP / Burp Suite
- 前端框架:React/Vue 自带转义,但拼接 HTML 仍危险
六、记忆口诀
“输入不信,输出转义;
DOM 别 HTML,Cookie 加 HttpOnly;
CSP 锁脚本,OWASP 来助力!”