当前位置: 首页 > news >正文

XSS攻击防御

目录
  • 背景和价值
      • 为什么需要输出编码?
      • 不同场景下的编码方式(白话版)
        • 1. 最常见场景:内容显示在HTML标签里(比如<div><span>中)
        • 2. 特殊场景:内容显示在HTML标签的属性里(比如valuehref中)
        • 3. 特殊场景:内容要在JavaScript代码里使用
        • 4. 特殊场景:内容作为URL的参数(比如跳转链接里)
      • 关键原则:“在哪里用,就用哪里的编码”
      • 总结
  • 参考资料

背景和价值

好的,咱们用白话再把“输出编码防XSS”这块讲透。核心思路就一句话:把用户输入的“危险字符”变成“无害字符”再显示到页面上

为什么需要输出编码?

XSS攻击的本质是:用户输入的内容里藏了恶意代码(比如<script>盗号</script>),如果直接显示到页面上,浏览器会把它当成正常代码执行,就中招了。

输出编码的作用就是:告诉浏览器“这只是普通文本,别当代码执行”。比如把<变成&lt;,浏览器看到&lt;就知道这只是个小于号,不是标签的开始,自然就不会执行里面的脚本了。

不同场景下的编码方式(白话版)

用户输入的内容可能会显示在不同地方(比如HTML标签里、JS代码里、URL里),每个地方的“危险字符”不一样,所以编码方式也不同。

1. 最常见场景:内容显示在HTML标签里(比如<div><span>中)

例子:用户在评论框输入<script>alert('偷你cookie')</script>,你要把这段内容显示在<div class="comment"></div>里。

危险:直接显示的话,浏览器会执行<script>里的代码,弹出弹窗+偷cookie。

编码方法:HTML编码(转义特殊字符)
把这些“危险字符”换成浏览器能看懂的“安全替身”:

  • <&lt;
  • >&gt;
  • &&amp;
  • "&quot;
  • '&#39;

编码后效果
原来的<script>alert('偷你cookie')</script>会变成:
&lt;script&gt;alert(&#39;偷你cookie&#39;)&lt;/script&gt;

浏览器看到这个,就会把它当成普通文本显示成<script>alert('偷你cookie')</script>,但不会执行里面的代码。

Java里怎么实现
用OWASP的编码工具(最靠谱),maven引入依赖:

<dependency><groupId>org.owasp.encoder</groupId><artifactId>encoder</artifactId><version>1.2.3</version>
</dependency>

然后在代码里调用:

import org.owasp.encoder.Encode;// 用户输入的危险内容
String userInput = "<script>alert('偷你cookie')</script>";
// 进行HTML编码
String safeContent = Encode.forHtml(userInput);
// 把safeContent输出到HTML标签里,比如用Thymeleaf、JSP的<c:out>等

2. 特殊场景:内容显示在HTML标签的属性里(比如valuehref中)

例子:用户输入" onclick="alert('攻击'),你要把它放到<input type="text" value="用户输入">value里。

危险:如果直接放进去,会变成<input value="" onclick="alert('攻击')">,用户点输入框就会触发弹窗。

编码方法:HTML属性编码(比普通HTML编码更严格)
除了转义<>等,还要转义更多可能闭合属性的字符(比如空格、引号)。

Java里怎么实现
用OWASP的forHtmlAttribute方法:

String userInput = "\" onclick=\"alert('攻击')";
// 专门针对HTML属性的编码
String safeAttr = Encode.forHtmlAttribute(userInput);
// 然后放到<input value="safeAttr">里

3. 特殊场景:内容要在JavaScript代码里使用

例子:用户输入'; alert('攻击'); //,你要把它放到JS代码里:var username = '用户输入';

危险:直接放进去会变成var username = ''; alert('攻击'); //';,JS会执行alert

编码方法:JavaScript编码(把字符转成Unicode编码)
比如把单引号'转成\u0027,双引号"转成\u0022,这样JS就不会把它当成代码分隔符了。

Java里怎么实现
用OWASP的forJavaScript方法:

String userInput = "'; alert('攻击'); //";
// 专门针对JS的编码
String safeJs = Encode.forJavaScript(userInput);
// 然后放到JS代码里:var username = '"+safeJs+"';

4. 特殊场景:内容作为URL的参数(比如跳转链接里)

例子:用户输入?page=1&user=admin<script>,你要把它拼到URL里:http://xxx.com?param=用户输入

危险:直接拼接可能导致URL格式错乱,甚至注入恶意参数。

编码方法:URL编码(把特殊字符转成%xx格式)
比如空格转成%20<转成%3C,确保参数是安全的。

Java里怎么实现
URLEncoder或者OWASP的forUriComponent

import java.net.URLEncoder;String userInput = "?page=1&user=admin<script>";
// URL编码(注意指定UTF-8编码)
String safeUrlParam = URLEncoder.encode(userInput, "UTF-8");
// 或者用OWASP的方法
String safeUrlParam2 = Encode.forUriComponent(userInput);
// 拼到URL里:http://xxx.com?param="+safeUrlParam

关键原则:“在哪里用,就用哪里的编码”

  • 显示在HTML标签里 → 用HTML编码
  • 放在HTML属性里 → 用HTML属性编码
  • 放到JS代码里 → 用JS编码
  • 作为URL参数 → 用URL编码

千万别混用!比如在JS里用HTML编码是没用的,照样可能被攻击。

总结

输出编码的核心就是:根据内容最终要出现的位置,用对应的编码方式把“危险字符”转成“无害字符”,让浏览器或脚本引擎把它们当成普通文本,而不是可执行的代码。这样不管用户输入什么花里胡哨的东西,最终都会变成安全的文本显示出来。

实际开发中,优先用成熟的编码库(比如OWASP Encoder),别自己写编码逻辑(容易漏考虑特殊情况)。

上面的代码示例展示了不同场景下的编码效果,实际开发中只需根据内容的使用位置,调用对应的编码方法即可有效防止XSS攻击。记住:编码后的数据只能在对应的场景中使用,不要跨场景复用。

参考资料

http://www.hskmm.com/?act=detail&tid=9501

相关文章:

  • imes开发部署
  • 思维题做题记录-1
  • 如何在极短时间内通透一个大型开源项目
  • 求 Ray Ping - Gon
  • LCT学习笔记
  • Visual Studio 2026 Insiders 重磅发布:AI 深度集成、性能飞跃、全新设计
  • 《刚刚问世》系列初窥篇-Java+Playwright自动化测试-29- 操作单选和多选按钮 - 下篇(详细教程) - 北京
  • 自定义注解实现服务分处理-策略模式
  • iOS26正式版全新风格!一文汇总实用新功能!
  • 远程控制应用的中的全球节点功能如何开启?插件类型、并发数量怎么选?
  • 借助Aspose.HTML控件,使用 Python 将 HTML 转换为 DOCX
  • openEuler 24.03 (LTS-SP2)安装mysql 8.0.41
  • 7.数据库归档异常检查与处理
  • Gitlab 关键字
  • 8.listener日志占用过大处理方法
  • 马建仓AI助手完成全链路升级:三十余项新能力重塑研发工作流
  • 线性回归与 Softmax 回归:深度学习基础模型解析 - 实践
  • 浏览器下载,一定要开启这个隐藏功能!
  • 开源项目进度管理系统 PJMan:让技术项目进度可视化、数据化的利器
  • 【光照】[漫反射]UnityURP兰伯特能量守恒吗?
  • Microsoft AI Genius 限时挑战赛:实战开启,等你应战!
  • DevSecOps革命:测试工具如何重塑企业数字化转型的质量防线
  • 3.sysaux tablesace 清理
  • 2.LOCK session
  • 2025 ~ 2026 游击 - gfoi
  • 【初赛】第二类斯特林数意义 - Slayer
  • 在AI技术快速实现功能的时代,挖掘新需求成为核心竞争力——某知名Android面试题库需求洞察
  • php本地搭建知识库实现rag遇到的一些问题解决方式
  • docker操作包括使用docker制作为接口
  • BuildingSystemPlugin使用指南