什么是 SQL 注入

Posted on Wed, 25 Dec 2024 10:34:01 +0800 by LiangMingJian


什么是 SQL 注入

SQL 注入是一种常见的网络安全漏洞和数据库攻击手段。

攻击者通过非法手段,在 Web 服务器预先定义好的数据库 SQL 语句中添加额外的 SQL 语句,在管理员不知情的情况下欺骗数据库执行非授权的任意查询,获取相应的数据信息。

比如,Web 服务器有这样一个登录接口 http://api.example/login,它支持这样的一个参数:

{
	"username": "admin",
	"password": "123456"
}

在登录接口 login 传入后参数后,Web 服务器将执行以下的 SQL 语句,从 User 表中查找用户名为 admin 密码为 123456 的用户记录:

SELECT * FROM User WHERE username = "admin" AND password = "123456";

正常情况下,这个 SQL 语句是没有任何问题的,但是,如果传入参数变成下面的样式,则情况就完全不同了:

{
	"username": "admin",
	"password": "" OR "1"="1"
}

不难看出,密码变成了 " OR "1"="1 。

此时,login 接口 SQL 语句中的 "123456" 会被替换为 " OR "1"="1,然后整个 SQL 语句会变成下面的这个样子:

SELECT * FROM User WHERE username = "admin" AND password = "" OR "1"="1";

显然,WHERE 条件变成了 username = "admin" AND password = "" 或(OR) "1"="1",前者用户名为 admin 和密码为空的用户必定为假,后者 1 = 1 必定为真,因此 False OR True 则必定为真。

现在,这个 SQL 语句会查出所有的用户数据!

这个就是 SQL 注入的作用,通过向接口传递非法的参数,让 SQL 语句错误执行,无视权限内容输出数据,窃取重要信息。

SQL 注入的入口

所有用户可以控制的输入点都可能成为 SQL 注入的入口。

SQL 注入的入口通常包括以下部分:

  • 网页中登录,搜索,注册,创建,修改等 Form 表单,即使用 POST 请求的所有接口。
  • 网页中所有涉及查询的 GET 接口。

除此之外,HTTP 请求头也有可能成为 SQL 注入的入口。

SQL 注入的防护

永远不要信任用户的输入,始终通过测试类型、长度、格式和范围来验证用户输入。

SQL 注入的防护手段可以关注以下几点:

  • 限定输入数据的长度和数据类型,防止有意造成的缓冲区溢出。
  • 限制变量的内容,只接受所需的值。 拒绝所有包含二进制数据、转义序列和注释字符的输入内容,防止注入。
  • 绝对不直接使用用户输入的内容来生成 SQL 语句,应当进行转换。
  • 绝不串联拼接未经验证的用户输入,因为字符串串联是 SQL 注入的主要输入点。
  • 将 SQL 逻辑封装在数据库中,然后通过参数调用,避免直接暴露 SQL 语句。
  • 使用 ORM 框架(对象关系映射框架)来自动处理 SQL 语句构建,减少拼接风险。

防范 SQL 注入验证用户输入时,应当对以下的特殊字符进行重点检查:

|字符‌|‌作用|‌示例注入|‌ |—|—|—| |‌单引号 '‌| 提前结束字符串,变更 SQL 语句 |' OR 1=1 --| |‌双引号 "‌| 提前结束字符串,变更 SQL 语句 |" OR 1=1 --| |‌分号 ;| 分隔已有 SQL 语句,插入新的 SQL 语句 |1; DROP TABLE users| |‌注释符 -- 或 /* */‌| 注释原来的 SQL 语句 |1' --| |‌逗号 ,‌| 分隔原来的 SQL 查询条件,跨权限查询更多数据 |UNION SELECT 1,2,3| |‌空格‌| 分隔 SQL 关键字,让数据库错误识别注入语句是一个新语句 |SELECT * FROM users| |‌AND/OR‌| 改变 SQL 逻辑条件 |id=1 OR 1=1| |‌UNION‌| 合并 SQL 查询结果,跨权限查询更多数据 |UNION SELECT password| |JOIN‌| 连接 SQL 查询结果,跨权限查询更多数据 |JOIN‌ password|

一般来说,SQL 防护要求限制所有数据库 SQL 语句中可能出现的关键字和特殊字符,以避免注入。

SQL 注入的绕过

需要注意的是,SQL 注入防护中特殊字符不能只是简单的限制在对字符形态进行判断,还需要考虑攻击者可能使用特殊方法绕过防护的情况。

比如,攻击者常用的 SQL 绕过方法有:

  • 大小写替换术‌:如使用 anD 代替 AND
  • ‌注释符大小写替换术‌:如 -- 变 ————
  • ‌特殊符号替换术‌:如 + 代替空格,%23 代替 #
  • 复写技术‌:如 anandd 代替 AND
  • ‌URL 编码技术‌:如 %20 代替空格,%0A 代替换行

SQL 注入的测试工具

开源的 SQL 注入测试工具:sqlmap

sqlmap