SQL注入步骤详解:从入门到理解防御原理

什么是SQL注入

在开发后台管理系统或网站登录功能时,很多人会把用户输入直接拼接到SQL语句中。比如一个简单的登录查询:

SELECT * FROM users WHERE username = '" + userInput + "' AND password = '" + passInput + "'

如果不对输入做处理,攻击者就能通过构造特殊字符串绕过验证。这就是SQL注入的起点。

第一步:发现可利用的输入点

常见的输入位置包括登录框、搜索栏、URL参数。比如访问一个商品页面:product.php?id=123,这里的id很可能对应数据库查询。

尝试在地址栏改成id=123',如果页面报错出现“MySQL syntax”之类的字样,说明后端没过滤单引号,可能存在漏洞。

第二步:判断数据表结构

确认存在漏洞后,可以用一些基础语法探测字段数量。例如使用ORDER BY逐个试:

product.php?id=123' ORDER BY 1-- 

然后改成ORDER BY 2ORDER BY 3……直到页面报错,就知道查询涉及几个字段了。

第三步:利用UNION提取数据

假设发现有3个字段,可以尝试合并一条伪造记录:

product.php?id=123' UNION SELECT 1,2,3-- 

如果页面上显示出数字2和3的位置,说明这两个字段能被渲染出来。这时候就可以替换为真实信息:

id=123' UNION SELECT 1,username,password FROM users-- 

一旦成功,用户的账号密码就会明文显示在网页某处。

第四步:获取更高权限信息

有些系统会记录管理员会话或保存敏感配置。可以通过注入查当前数据库名、版本等信息:

SELECT database(), version()

还可以尝试读取文件,比如LOAD_FILE('/etc/passwd'),前提是权限足够且路径正确。

实际场景中的例子

想象你在测试自家公司的测试站点,发现员工查询接口用了拼接SQL。输入姓名“张三' OR '1'='1”后,整个员工列表都被导出——这正是典型的字符型注入。

别小看这种写法,很多老系统还在用字符串拼接,尤其是一些内部报表工具。

如何有效防范

最根本的方法是使用预编译语句(Prepared Statement)。比如Java里的PreparedStatement,PHP中的PDO绑定参数:

$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$user_id]);

这样即使输入包含单引号也不会破坏语义。另外,最小权限原则也很重要——数据库账号不要给SELECT以外的多余权限。

结语

了解SQL注入不是为了搞破坏,而是更好地写出安全的代码。尤其是在处理表格类数据展示时,任何来自前端的筛选、排序、分页参数都可能成为突破口。多一分警惕,少一次泄露。