跨站点脚本攻击(Cross-Site Scripting,XSS)是一种常见的安全漏洞,攻击者通过在网页中注入恶意脚本,从而在用户浏览网页时执行这些脚本。XSS 攻击通常用于窃取用户数据、劫持用户会话、篡改网页内容或传播恶意软件。


XSS 攻击的类型

XSS 攻击主要分为以下三种类型:

1. 反射型 XSS(Reflected XSS)

  • 攻击者将恶意脚本作为参数注入到 URL 中,服务器将这些参数直接返回给用户的浏览器并执行。
  • 通常通过诱使用户点击恶意链接来触发。
  • 示例:
      http://example.com/search?query=

    如果服务器未对输入进行过滤,浏览器会执行 <script> 标签中的代码。

2. 存储型 XSS(Stored XSS)

  • 攻击者将恶意脚本提交到服务器并存储在数据库中,当其他用户访问包含该脚本的页面时,脚本会被执行。
  • 常见于评论区、用户资料等用户输入内容的地方。
  • 示例:
    攻击者在评论区提交:

      alert('XSS')

    其他用户访问该页面时,脚本会被执行。

3. 基于 DOM 的 XSS(DOM-based XSS)

  • 攻击通过修改页面的 DOM 结构来实现,不涉及服务器端。
  • 恶意脚本通过 URL 或用户输入直接修改页面的 DOM 元素。
  • 示例:
     document.getElementById('output').innerHTML = window.location.hash.substring(1);

    如果 URL 中包含恶意脚本(如 #<script>alert('XSS')</script>),脚本会被执行。


XSS 攻击的危害

  1. 窃取用户数据:攻击者可以窃取用户的 Cookie、会话令牌等敏感信息。
  2. 劫持用户会话:攻击者可以冒充用户执行操作。
  3. 篡改网页内容:攻击者可以修改页面内容,诱导用户进行恶意操作。
  4. 传播恶意软件:通过注入恶意脚本,攻击者可以引导用户下载或安装恶意软件。

防御 XSS 攻击的措施

为了防止 XSS 攻击,开发者需要采取多层次的安全措施:

1. 输入验证和过滤

  • 对所有用户输入进行严格的验证和过滤,确保输入内容符合预期格式。
  • 使用白名单机制,只允许特定的字符或格式。
  • 示例:
     // 在 .NET Core 中使用正则表达式验证输入
     if (!Regex.IsMatch(input, @"^[a-zA-Z0-9]+$"))
     {
         throw new ArgumentException("Invalid input");
     }

2. 输出编码

  • 在将用户输入内容输出到页面时,对特殊字符进行 HTML 编码。
  • 示例:
     // 在 .NET Core 中使用 HtmlEncoder 进行编码
     var encodedInput = System.Text.Encodings.Web.HtmlEncoder.Default.Encode(userInput);

3. 使用安全的 API

  • 避免使用 innerHTMLdocument.write 等不安全的 API,改用 textContentinnerText
  • 示例:

     // 不安全的写法
     document.getElementById('output').innerHTML = userInput;
    
     // 安全的写法
     document.getElementById('output').textContent = userInput;

4. 设置 HTTP 安全头

  • 使用 Content-Security-Policy(CSP)头来限制页面中可以执行的脚本来源。
  • 示例:
     Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com;
  • 使用 HttpOnlySecure 标志来保护 Cookie:
     Set-Cookie: sessionId=abc123; HttpOnly; Secure

5. 使用框架的内置防护

  • 现代前端框架(如 React、Vue、Angular)和后端框架(如 .NET Core、Django)通常内置了 XSS 防护机制。
  • 确保使用框架的最新版本,并遵循其安全最佳实践。

6. 定期安全测试

  • 使用自动化工具(如 OWASP ZAP、Burp Suite)或手动测试来检测 XSS 漏洞。
  • 定期进行代码审查和安全审计。

示例:防御 XSS 攻击的代码

前端(JavaScript)

// 安全的输出方式
const userInput = "<script>alert('XSS')</script>";
document.getElementById('output').textContent = userInput;

后端(.NET Core)

// 使用 HtmlEncoder 对输出进行编码
var encodedInput = System.Text.Encodings.Web.HtmlEncoder.Default.Encode(userInput);
ViewData["SafeInput"] = encodedInput;

后端(Node.js + Express)

const escape = require('escape-html');
app.get('/search', (req, res) => {
    const query = escape(req.query.q); // 对输入进行编码
    res.send(`You searched for: ${query}`);
});

总结

XSS 攻击是一种严重的安全威胁,但通过输入验证、输出编码、使用安全的 API 和设置 HTTP 安全头等措施,可以有效防御 XSS 攻击。开发者应始终将安全性作为开发流程的重要组成部分,并定期进行安全测试和代码审查。

最后修改日期: 2025年1月14日

作者