简单的SQL注入| 青训营笔记

111 阅读2分钟

这是我参与「第五届青训营 」笔记创作活动的第2天,今天我学习了sql注入和防护的方法。

SQL注入

SQL注入即是指 web应用程序 对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的 SQL语句 ,在管理员不知情的情况下实现非法操作,以此来实现欺骗 数据库服务器 执行非授权的任意查询,从而进一步得到相应的数据信息。

我们简单的来写一个sql查询语句,以查看用户是否有权限登录为例子

select * from users where name = 'abc' and password = 'def' limit 1

通常用户的用户名和密码都是包含在请求中,如果我们在用户名中添加' -- 那么查询语句就会变成以下的情况

select * from users where name = 'abc' -- ' and password = 'def' limit 1

这条语句中password失效了,无论password输入什么都不再重要。我们再改一下

select * from users where name = 'abc' or 1=1 -- ' and password = 'def' limit 1

那么请求中的用户名都不再重要,这条语句一定能查到结果。

这就是一个简单的sql注入。下面来看看如何防护sql注入攻击。

  1. 关键字符过滤,将可能触发sql注入的关键词进行过滤,通常来说,攻击者会构造两层的sql注入用来防止单层的过滤让注入失败。
  2. 预编译sql,sql注入的发生本质上是因为指令与数据的不分离,如果我们可以将指令确定下来,那么无论传入的数据是什么样的,都不会改变指令的运行,这就是预编译sql。事先将带参数的sql传给数据库,让数据库将其进行编译,下次再执行的时候仅需要传入参数。

通常来说orm框架都会对sql注入进行防护,手动拼接sql的服务是sql注入的重灾区。下来再讨论一个orm也可能无法防护的地方,同样也是事故高发地点,就是order by。由于数据库的特性,order by 后面加排序的字段,这种参数是无法进行预编译的。所以通常会在这里拼接sql。所以建议这里对传入的参数进行校验,或者将可能出现的字段都进行一次预编译,都不失为一个办法。