Appearance
9.5 防止 XSS(htmlspecialchars)
XSS(跨站脚本攻击)是一种常见的网络安全漏洞,攻击者通过在网页中注入恶意脚本,当用户浏览该网页时,恶意脚本会在用户浏览器中执行。
XSS 攻击类型
- 存储型 XSS:恶意代码被存储在服务器数据库中,当其他用户访问相关页面时触发
- 反射型 XSS:恶意代码通过 URL 参数传递,服务器将其反射回浏览器执行
- 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 标签: <b>粗体</b></li>
<li>JavaScript: <script>alert('XSS')</script></li>
<li>事件属性: <div onclick="alert('XSS')">点击我</div></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>注意事项
- 始终对用户输入进行处理:任何来自用户的输入都应该被视为不可信
- 使用正确的字符编码:确保使用 UTF-8 编码,避免字符集问题
- 设置适当的 ENT_QUOTES 参数:转换单引号和双引号,提供更全面的保护
- 对输出进行编码:不仅要处理输入,还要确保在输出时进行适当的编码
- 使用内容安全策略 (CSP):通过 HTTP 头部设置 CSP,限制可以执行的脚本来源
练习
- 测试不同类型的 XSS 攻击向量
- 实现一个包含防 XSS 措施的表单
- 比较不同防 XSS 方法的效果
