Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 

Repository files navigation

XSS (Cross-Site Scripting) 攻击与防护指南

什么是 XSS 攻击?

XSS (Cross-Site Scripting) 是一种能够将恶意脚本注入 Web 应用的攻击方式。

XSS 攻击原理

XSS 攻击的核心是破坏浏览器的同源策略(Same-Origin Policy)。攻击者通过欺骗目标网站执行恶意代码,使其在网站自身的上下文中运行,从而获得与网站代码相同的权限。

所有 XSS 攻击都依赖于网站做两件事:

  1. 接受可能由攻击者精心制作的输入
  2. 在页面中包含此输入而不进行清理(sanitizing)

XSS 攻击类型

1. 客户端代码注入

  • 发生在浏览器中,通过客户端渲染过程
  • 恶意代码通过 DOM 操作(如 innerHTML)注入
  • 常见于单页应用(SPA)

2. 服务端代码注入

  • 发生在服务器端,通过模板渲染过程
  • 恶意代码在服务器构建页面时注入
  • 常见于服务端渲染应用

3. 存储型 XSS(持久型)

  • 恶意脚本存储在数据库中
  • 每次用户访问页面时都会执行
  • 危害最大,影响所有访问用户

防护措施

1. 输出编码(Output Encoding)

将输入字符串中的危险字符进行转义,使其被视为文本而非可执行代码。

示例转换:

< → &lt;
> → &gt;
" → &quot;
' → &#x27;
& → &amp;

现代框架自动编码:

  • Django 模板引擎自动执行输出编码
  • React JSX 自动编码嵌入值

2. 内容清理(Sanitization)

当需要插入 HTML 内容时,使用清理库移除不安全的特性。

推荐工具:

  • DOMPurify - 被 OWASP 推荐的 HTML 清理库

示例:

// 危险输入
const input = '<img src=x onerror=alert("XSS")>Click me</img>';

// DOMPurify 清理后
const clean = DOMPurify.sanitize(input);
// 结果: 'Click me'

3. 可信类型(Trusted Types API)

确保输入在传递给危险 API 之前总是经过清理。

危险的 Web API:

  • element.innerHTML
  • document.write()
  • eval()
  • setTimeout() (字符串参数)

使用示例:

// 创建策略
const policy = trustedTypes.createPolicy('myPolicy', {
  createHTML: (string) => DOMPurify.sanitize(string)
});

// 安全使用
element.innerHTML = policy.createHTML(userInput);

4. 内容安全策略(CSP)

作为备用防护,即使恶意脚本进入页面也能阻止其执行。

严格 CSP 配置

基于 Nonce 的 CSP:

Content-Security-Policy:
  script-src 'nonce-{RANDOM}' 'strict-dynamic';
  object-src 'none';
  base-uri 'none';

基于哈希的 CSP:

Content-Security-Policy:
  script-src 'sha256-{HASHED_INLINE_SCRIPT}' 'strict-dynamic';
  object-src 'none';
  base-uri 'none';

CSP 选择指南

  • Nonce-based CSP: 适用于服务端渲染的页面
  • Hash-based CSP: 适用于静态页面或单页应用

代码重构要求

使用严格 CSP 时需要重构以下模式:

1. 内联事件处理器

<!-- 危险 -->
<button onclick="doSomething()">Click</button>

<!-- 安全 -->
<button id="myButton">Click</button>
<script nonce="{NONCE}">
  document.getElementById('myButton').addEventListener('click', doSomething);
</script>

2. JavaScript URI

<!-- 危险 -->
<a href="javascript:void(0)" onclick="doSomething()">Link</a>

<!-- 安全 -->
<a href="#" id="myLink">Link</a>
<script nonce="{NONCE}">
  document.getElementById('myLink').addEventListener('click', function(e) {
    e.preventDefault();
    doSomething();
  });
</script>

3. eval() 函数

// 危险
const obj = eval('(' + jsonString + ')');

// 安全
const obj = JSON.parse(jsonString);

防护检查清单

  • 使用自动输出编码的模板引擎
  • 了解不同文档上下文的编码需求
  • 需要插入 HTML 时使用可信的清理库
  • 实施严格的 CSP(基于 nonce 或哈希)
  • 重构内联事件处理器和 JavaScript URI
  • 避免使用 eval() 和类似的代码执行函数
  • 定期进行安全审计和代码审查

部署建议

  1. 开发阶段: 使用 Lighthouse 检查 CSP 配置
  2. 测试阶段: 使用 Content-Security-Policy-Report-Only 头进行测试
  3. 生产阶段: 部署完整的 CSP 策略

注意事项

严格的 CSP 虽然提供强大保护,但在某些情况下仍可能被绕过:

  • 通过可信脚本中的 DOM 操作漏洞
  • 利用 'strict-dynamic' 的特性
  • 通过 JSONP 等机制

因此,CSP 应作为深度防护策略的一部分,而不是唯一的防护措施。

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages