防御xss需构建多层防线,核心是白名单过滤、上下文敏感编码与安全响应头结合;spring boot中可用@pattern、@email等注解实现输入校验,严禁手动拼接html。

防御XSS攻击不能只靠某一个环节,关键是在数据从用户输入到浏览器渲染的整个链路上建立多层防线。最有效的方式是“白名单过滤 + 上下文敏感编码 + 安全响应头”三者结合,而不是依赖简单的黑名单替换或单点拦截。
对所有用户输入做白名单校验
拒绝一切非必要字符,比尝试拦住所有危险字符更可靠。例如:用户名只允许字母、数字、下划线和短横线;手机号只接受数字和+、-、空格;邮箱使用标准正则验证格式。Spring Boot中可配合@Pattern、@Email等注解,在Controller入参或DTO字段上直接声明约束。
- 避免在业务逻辑里手动拼接HTML字符串,比如String html = "" + userInput + ""
- 禁用全局replaceAll("
- 富文本场景必须使用专业净化库(如jsoup或OWASP Java HTML Sanitizer),并配置严格白名单标签和属性
输出时按HTML上下文做精准编码
同一段用户数据,在不同位置渲染需要不同编码方式:插入HTML正文要HTML实体编码,写入JavaScript字符串要JS字符串编码,放在URL参数里要URL编码。用Thymeleaf、JSP EL或FreeMarker等现代模板引擎,默认已开启自动转义,但需确认未被显式关闭(如Thymeleaf的th:utext)。
- 不要在JS代码中直接拼接用户数据:var name = "${user.name}"; → 应改用var name = "${#strings.escapeXml(user.name)}";
- 动态生成URL时,对参数值单独调用URLEncoder.encode(value, "UTF-8")
- 避免使用document.write()、innerHTML、eval()等高危API操作用户数据
启用HTTP安全响应头
利用浏览器原生能力辅助防护,属于低成本高收益的兜底措施。关键头包括:
- Content-Security-Policy:限制脚本仅从指定域名加载,禁止内联脚本('unsafe-inline')和eval('unsafe-eval')。示例:Content-Security-Policy: script-src 'self' https://cdn.example.com;
- X-Content-Type-Options: nosniff:防止MIME类型混淆导致的脚本执行
- X-Frame-Options: DENY 或 Content-Security-Policy: frame-ancestors 'none':防御点击劫持,间接降低XSS利用成功率
- Set-Cookie 中添加 HttpOnly 和 Secure 标志,阻止document.cookie读取会话凭证
加强服务端与前端协同防护
DOM型XSS完全发生在前端,后端无法拦截,因此前端也需主动设防。Vue/React默认对插值表达式做转义,但v-html、dangerouslySetInnerHTML等API仍需谨慎使用;所有通过location.search、location.hash、localStorage读取的数据,在写入DOM前必须经过DOMPurify等库净化。
- 管理后台等高权限页面,可增加二次确认机制(如修改关键配置时弹出密码验证)
- 日志系统记录所有含script、onxxx、javascript:等特征的请求,便于攻击溯源
- 定期用ZAP、Burp Suite扫描,配合人工测试常见输入点(搜索框、评论区、404页面、重定向跳转url参数)











