防御SQL注入和XSS的核心是两条:所有数据库操作必须用prepare()+execute()预处理,所有用户数据输出到HTML前必须无条件调用htmlspecialchars($data, ENT_QUOTES | ENT_HTML5, 'UTF-8');其他措施均为这两条的加固或支撑。

防御SQL注入和XSS攻击,核心就两条:所有数据库操作必须用预处理语句,所有用户数据输出到HTML前必须过htmlspecialchars()。其他措施都是围绕这两点加固,不是替代方案。
用prepare()+execute()彻底隔离SQL逻辑与用户输入
拼接SQL字符串(比如"SELECT * FROM users WHERE id = " . $_GET['id'])是高危写法,无论加不加addslashes()或mysqli_real_escape_string(),都不能保证安全。
- 必须使用PDO或MySQLi的预处理功能,占位符(
?或:name)只代表参数位置,不参与SQL解析 - PDO默认开启模拟预处理(
PDO::ATTR_EMULATE_PREPARES = true),需显式关闭:$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false),否则数据库层无法真正校验类型 - 整数ID等明确类型的参数,绑定时指定类型更稳妥,例如
$stmt->bind_param("i", $id)(MySQLi)或$stmt->bindValue(':id', $id, PDO::PARAM_INT)(PDO) - 避免在循环中反复调用
bindParam()(传引用),改用bindValue()防止值被意外覆盖
所有动态HTML输出无条件调用htmlspecialchars()
不是“看起来像HTML才转义”,而是只要内容会插入HTML上下文(包括<input value="...">、<div>...</div>、<script>var name = "...";</script>),就必须转义。
- 调用时三个参数必须写全:
htmlspecialchars($data, ENT_QUOTES | ENT_HTML5, 'UTF-8')。缺了ENT_QUOTES,单引号不转义,<img src="x" onerror="alert(1)" alt="PHP网站搭建安全:如何防御SQL注入与XSS跨站脚本攻击" >类攻击仍可触发 - 不要对富文本(如后台编辑器内容)直接
htmlspecialchars()——这会让所有标签变成纯文本。应使用HTMLPurifier等白名单库清洗,只保留<p></p>、<strong></strong>等安全标签 - URL路径中的用户数据用
rawurlencode(),查询参数用urlencode(),别混用htmlspecialchars()
补充但不可替代的基础防线
预处理和输出编码是主干,这些是支撑主干的必要结构:
立即学习“PHP免费学习笔记(深入)”;
-
输入验证走白名单:比如手机号只允许数字和
+、-,邮箱用filter_var($email, FILTER_VALIDATE_EMAIL),不是简单删掉<script></script> -
数据库账号最小权限:Web应用连接数据库的账号,只授予所需表的
SELECT/INSERT/UPDATE权限,禁用DROP、CREATE、LOAD_FILE等高危权限 -
HTTP安全头补位:设置
X-Content-Type-Options: nosniff防MIME混淆,X-Frame-Options: DENY防点击劫持,Content-Security-Policy限制脚本来源(如script-src 'self')



















