2020-06-22 15:17:22
PHP防止UNION注入的核心方法是使用参数化查询(预处理语句),通过分离数据与代码彻底阻断注入路径。 以下是具体防护措施及实施要点:
一、核心防御手段:参数化查询(预处理语句)PDO示例:$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");$stmt->bindParam(':id', $_GET['id'] ?? '', PDO::PARAM_INT); // 明确参数类型$stmt->execute();
用户输入1 UNION SELECT @@version, NULL会被视为字符串值,无法改变SQL结构。
MySQLi示例:$mysqli = new mysqli('localhost', 'user', 'pass', 'test');$stmt = $mysqli->prepare("SELECT * FROM users WHERE id = ?");$stmt->bind_param("i", $_GET['id'] ?? 0); // "i"表示整数类型$stmt->execute();
最小权限原则:
数据库用户仅授予必要权限(如SELECT, INSERT, UPDATE),避免使用root等高权限账户。
示例:Web应用用户无需DROP TABLE或FILE权限,限制攻击者破坏范围。
严格输入验证与过滤:
对输入进行类型检查(如强制转换为整数)、长度限制、白名单过滤。
示例:若ID字段预期为整数,使用intval($_GET['id'])过滤。
Web应用防火墙(WAF):
部署WAF过滤HTTP请求中的常见攻击模式(如SQL注入关键词)。
适用场景:零日漏洞或未修补的应用程序提供额外防护层。
错误信息管理:
生产环境隐藏数据库错误详情,记录至日志并显示通用提示。
风险:错误信息可能暴露表名、字段名等敏感数据。
定期安全审计与代码审查:
人工审查结合自动化工具(如静态分析工具)识别潜在漏洞。
重点检查数据库交互代码,尤其是未使用预处理语句的部分。
原始查询:$query = "SELECT * FROM products WHERE category = '" . $_GET['category'] . "'";
攻击者输入:electronics' UNION SELECT username, password FROM users --
最终SQL:SELECT * FROM products WHERE category = 'electronics' UNION SELECT username, password FROM users --'
结果:合并两个查询结果,泄露用户表数据。
观察错误信息:
输入单引号'触发数据库错误,若错误信息返回页面,可能存在漏洞。
利用ORDER BY推断列数:
测试?id=1 ORDER BY 10 --+,逐步减少数字直至不报错,确定原始查询列数。
构造UNION SELECT语句:
确定列数后,替换数字为数据库函数或子查询:
示例:?id=1 UNION SELECT null, username, password FROM users --+
盲注技术:
布尔盲注:通过条件语句(如AND 1=1)观察页面变化。
时间盲注:利用延时函数(如SLEEP(5))判断条件真假。
自动化工具:
使用SQLMap自动识别注入点并尝试多种技术,但开发者应优先修复代码漏洞。
防御UNION注入的关键在于数据与代码分离,通过预处理语句实现这一目标,并辅以最小权限、输入验证等措施构建多层次防护。开发者需养成安全编码习惯,定期审计代码,避免依赖单一防御手段。