XSS攻击及其防范

在网络安全领域,跨站脚本攻击(XSS)是一种常见的攻击手段,它允许攻击者在用户的浏览器上执行恶意脚本。虽然技术上可能存在几种不同类型的XSS,本文将重点讨论两种类型:存储型和非存储型XSS。

存储型XSS攻击

考虑一个社交网络应用,用户可以发布帖子,这些帖子将出现在他们所有联系人的时间线上。后端逻辑可能如下所示: $posts = get_posts_for_user($user_id); foreach ($posts as $post) { ?>

username; ?>

body; ?>

这是一个非常简化的例子,但希望能理解。服务器端代码检索了登录用户的所有相关帖子,然后逐个列出。

现在考虑如果一个用户的联系人提交了一个包含以下内容的帖子: Feeling hacky today! <script> // 恶意代码 </script> 每当这个帖子被另一个用户的浏览器渲染时,脚本标签就会执行。这里留空是为了简洁,但可以想象攻击者可能会执行的操作,例如:

  • 下载恶意文件到用户的计算机
  • 更改其他帖子的本地显示内容,或者特定人的帖子
  • 破坏社交媒体网站
  • 播放用户无法关闭的隐藏媒体
因为帖子被保存(即存储)到了社交网络应用的数据库中,所以这被归类为存储型XSS攻击。

非存储型XSS攻击

考虑一个在线商店,允许用户搜索产品。搜索词存储在查询字符串中,所以一个示例URL可能看起来像这样: https://www.onlinestore.com/search?q=Cool+products 服务器端代码可能如下所示: $results = do_search($_GET['q']); foreach ($results as $result) { // ... } 在这种情况下,想象一个攻击者通过电子邮件或其他消息向目标用户发送了以下链接: <a href="https://www.onlinestore.com/search?q=<script></script>"> Products on sale </a> 同样,这里留空是为了简洁,但可以想象攻击者可能会尝试的操作,例如:

  • 更改页面的HTML以包含或修改产品列表
  • 更改产品的链接,使其指向一个钓鱼网站
  • 一般破坏在线商店
因为恶意内容来自查询字符串而不是数据库记录,因此它没有被“存储”,所以它被归类为非存储型。

XSS攻击的“跨站”含义

通过这两个例子,可能会像欧比旺一样疑惑“跨站脚本”这个名字的来源,因为似乎没有什么东西是“跨站”的。根据维基百科,XSS这个名字是因为在早期利用这种漏洞时,通常是通过一个网站调用另一个网站来实现的。这有点误导,因为实际上并不需要第二个网站来利用这个漏洞。

虽然适当的预防措施可能取决于上下文,但建议从以下两个选项开始:

  • 总是对非信任输入进行编码,如果必须显示,例如将 <script> 编码为 <script> 并仅显示而不是执行脚本标签。
  • 如果用户提交的输入必须逐字显示(例如:允许用户自定义帖子样式的论坛),考虑使用支持允许元素和属性白名单的HTML清理工具。违反HTML清理器配置的用户提交的输入应该被拒绝。
不建议尝试像在《.NET Core WebAPI中防止XSS》中提到的那样预先清理所有传入请求。在实践中,发现这并不可行,而简单地在输出时编码数据往往是更好的方法。

例如,JavaScript代码: <script> document.write('Damn'); </script>

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485