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