Skip to content

9.5 防止 XSS(htmlspecialchars)

XSS(跨站脚本攻击)是一种常见的网络安全漏洞,攻击者通过在网页中注入恶意脚本,当用户浏览该网页时,恶意脚本会在用户浏览器中执行。

XSS 攻击类型

  1. 存储型 XSS:恶意代码被存储在服务器数据库中,当其他用户访问相关页面时触发
  2. 反射型 XSS:恶意代码通过 URL 参数传递,服务器将其反射回浏览器执行
  3. DOM 型 XSS:恶意代码在客户端浏览器中执行,不经过服务器

防止 XSS 的方法

1. 使用 htmlspecialchars() 函数

htmlspecialchars() 函数可以将特殊字符转换为 HTML 实体,防止浏览器将其解析为 HTML 或 JavaScript。

2. 使用 htmlentities() 函数

htmlentities() 函数可以将所有可转换的字符转换为 HTML 实体,比 htmlspecialchars() 更彻底。

3. 使用 strip_tags() 函数

strip_tags() 函数可以移除 HTML 和 PHP 标签,只保留纯文本。

4. 输入验证

对用户输入进行严格验证,限制输入内容的格式和长度。

5. 输出编码

在将用户输入输出到页面之前,进行适当的编码处理。

示例代码

基本防 XSS 示例

php
<?php
// xss_prevention.php
$userInput = '';
$safeOutput = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (isset($_POST['input'])) {
        $userInput = $_POST['input'];
        
        // 使用 htmlspecialchars() 防止 XSS
        $safeOutput = htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
    }
}
?>

<!DOCTYPE html>
<html>
<head>
    <title>防止 XSS 攻击示例</title>
    <style>
        .input-area { margin: 10px 0; }
        .output-area { margin: 10px 0; padding: 10px; border: 1px solid #ddd; }
    </style>
</head>
<body>
    <h2>防止 XSS 攻击示例</h2>
    
    <form action="xss_prevention.php" method="post">
        <div class="input-area">
            <label>输入内容: <br>
                <textarea name="input" rows="5" cols="50"><?php echo isset($userInput) ? htmlspecialchars($userInput) : ''; ?></textarea>
            </label>
        </div>
        <input type="submit" value="提交">
    </form>
    
    <?php if ($safeOutput): ?>
        <div class="output-area">
            <h3>安全输出:</h3>
            <?php echo $safeOutput; ?>
        </div>
        <div class="output-area">
            <h3>原始输出(不安全):</h3>
            <?php echo $userInput; ?>
        </div>
    <?php endif; ?>
    
    <div class="example">
        <h3>测试用例:</h3>
        <ul>
            <li>普通文本: Hello World</li>
            <li>HTML 标签: &lt;b&gt;粗体&lt;/b&gt;</li>
            <li>JavaScript: &lt;script&gt;alert('XSS')&lt;/script&gt;</li>
            <li>事件属性: &lt;div onclick="alert('XSS')"&gt;点击我&lt;/div&gt;</li>
        </ul>
    </div>
</body>
</html>

更全面的防 XSS 示例

php
<?php
// comprehensive_xss_prevention.php
function sanitizeInput($input) {
    return htmlspecialchars(trim($input), ENT_QUOTES, 'UTF-8');
}

function sanitizeHTML($input) {
    // 只允许特定的 HTML 标签
    $allowedTags = '<p><br><b><i><u><h1><h2><h3><h4><h5><h6><ul><ol><li><a>';
    return strip_tags(trim($input), $allowedTags);
}

$userInput = '';
$safeOutput = '';
$htmlOutput = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (isset($_POST['input'])) {
        $userInput = $_POST['input'];
        $safeOutput = sanitizeInput($userInput);
        $htmlOutput = sanitizeHTML($userInput);
    }
}
?>

<!DOCTYPE html>
<html>
<head>
    <title>全面防 XSS 示例</title>
    <style>
        .input-area { margin: 10px 0; }
        .output-area { margin: 10px 0; padding: 10px; border: 1px solid #ddd; }
    </style>
</head>
<body>
    <h2>全面防 XSS 示例</h2>
    
    <form action="comprehensive_xss_prevention.php" method="post">
        <div class="input-area">
            <label>输入内容: <br>
                <textarea name="input" rows="5" cols="50"><?php echo isset($userInput) ? htmlspecialchars($userInput) : ''; ?></textarea>
            </label>
        </div>
        <input type="submit" value="提交">
    </form>
    
    <?php if ($safeOutput): ?>
        <div class="output-area">
            <h3>完全转义(纯文本):</h3>
            <?php echo $safeOutput; ?>
        </div>
        <div class="output-area">
            <h3>允许特定 HTML 标签:</h3>
            <?php echo $htmlOutput; ?>
        </div>
    <?php endif; ?>
</body>
</html>

注意事项

  1. 始终对用户输入进行处理:任何来自用户的输入都应该被视为不可信
  2. 使用正确的字符编码:确保使用 UTF-8 编码,避免字符集问题
  3. 设置适当的 ENT_QUOTES 参数:转换单引号和双引号,提供更全面的保护
  4. 对输出进行编码:不仅要处理输入,还要确保在输出时进行适当的编码
  5. 使用内容安全策略 (CSP):通过 HTTP 头部设置 CSP,限制可以执行的脚本来源

练习

  1. 测试不同类型的 XSS 攻击向量
  2. 实现一个包含防 XSS 措施的表单
  3. 比较不同防 XSS 方法的效果

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