Web 安全

XSS (跨站脚本攻击)

约 4 分钟阅读

什么是 XSS (跨站脚本攻击)

XSS (Cross-Site Scripting) 是一种利用 Web 应用程序漏洞,在用户浏览器中执行恶意 JavaScript 的攻击手法。由于注入的脚本在受害者浏览器中以合法网站的上下文执行,因此可以造成广泛的危害,包括窃取 Cookie、会话劫持、重定向到钓鱼页面、记录键盘输入等。

XSS 多年来一直位列 OWASP Top 10,是 Web 应用程序开发者首先应该了解的安全风险之一。

XSS 的三种类型

XSS 根据攻击机制分为三种类型。

反射型 XSS (Reflected XSS)

当用户提交的数据 (URL 参数、表单输入等) 被直接反映在服务器的响应中时发生。攻击者构造包含恶意脚本的 URL,诱使受害者点击。搜索结果页面或错误消息中未经转义直接显示输入值是典型案例。

存储型 XSS (Stored XSS)

恶意脚本被保存在服务器的数据库中,每当其他用户查看该数据时脚本就会执行。论坛帖子、用户资料、评论区等都可能成为攻击目标。与反射型不同,受害者无需点击特定 URL,因此影响范围更广。

DOM 型 XSS

不是在服务器端,而是在客户端 JavaScript 操作 DOM (Document Object Model) 时发生。用户输入通过 document.locationdocument.URLinnerHTML 等以不安全的方式插入 DOM。由于服务器响应中不包含恶意代码,因此无法通过服务器端日志检测。

具体攻击场景

通过具体场景来理解 XSS 攻击是如何执行的。

通过 Cookie 窃取实现会话劫持

攻击者在论坛上发布脚本。当其他用户查看该帖子时,浏览器中保存的会话 Cookie 会被发送到攻击者的服务器。攻击者使用该 Cookie 劫持受害者的会话,以受害者的身份登录并操作网站。

如果 Cookie 设置了 HttpOnly 属性,JavaScript 的访问将被阻断,因此可以防御此攻击。但仍有许多网站未设置 HttpOnly

注入钓鱼表单

利用 XSS 在合法网站上显示伪造的登录表单,窃取用户的认证信息。由于 URL 仍然是合法域名,用户极难察觉伪造表单。

防御策略与实现最佳实践

XSS 防御的基本思路是将输入验证、输出转义和浏览器保护功能相结合的纵深防御。

  • 彻底的输出转义:根据输出上下文 (HTML、JavaScript、URL、CSS 等) 进行适当的转义处理。在 HTML 上下文中,将 <>&"' 转换为实体
  • 引入 CSP (Content Security Policy):禁止内联脚本执行,仅允许来自许可域的脚本运行。即使发生 XSS,也能阻止攻击者脚本的执行
  • Cookie 的 HttpOnly 属性:为会话 Cookie 设置 HttpOnly,阻断 JavaScript 的访问
  • 输入验证:在接受用户输入时,验证是否符合预期格式 (数字、邮箱地址等)。但仅靠输入验证无法完全防止 XSS,需与输出转义配合使用
  • 模板引擎的自动转义:React、Vue、Angular 等框架默认对输出进行转义。应尽量减少 dangerouslySetInnerHTML (React) 或 v-html (Vue) 的使用
  • 安全头配置:通过 X-Content-Type-Options: nosniff 防止 MIME 类型嗅探

通过 WAF 检测 XSS 模式也很有效,但 WAF 可能被绕过,因此不能替代应用层面的防御措施。

常见误解

XSS 只是篡改页面外观的轻微漏洞
XSS 可导致会话劫持、认证信息窃取、恶意软件分发、管理员权限夺取等严重危害。特别是存储型 XSS 会影响所有访问该网站的用户,影响范围极其广泛。
验证输入就能防止 XSS
输入验证只是防御的一层。攻击者通过编码转换、Unicode 规范化、上下文切换等多种手法绕过验证。根本性的防御措施是根据输出上下文进行转义处理,并建议与 CSP 配合使用。

XSS 与 CSRF 的比较

XSS

在受害者的浏览器中执行攻击者的脚本。利用网站对用户的信任。防御措施为输出转义和 CSP。主要危害包括 Cookie 窃取和会话劫持。

CSRF

从受害者的浏览器伪造合法请求。利用用户对网站的信任。防御措施为令牌验证和 SameSite Cookie。主要危害为执行非预期的操作。

分享

相关术语