前言
引用书中介绍,SQL注入就是通过把SQL命令伪装成正常的HTTP请求参数传递到服务器,欺骗服务器最终执行恶意的SQL命令,达到入侵目的。达到的危害有:
- 查询非授权信息
- 修改数据库数据
- 改变表结构甚至删除表
- 获取服务器root权限
注入原理
某网站的登录请求如下:
url: http://api.adbc.com/user/login
method: post
body: {"username": "xx", "pass":"xx"}
后端代码如下:
# 截取关键部分
sql = "select * from user where username='xx' and pass='xx'"
result = mysqlcursor.execute(sql)
if len(result) == 1:
nickname = result["nickname"]
...
正常的情况就不说了,来说说怎么攻击的:
我在前端输入随便一个有效的用户名比如吴君如,密码是 ' or '1'='1, ok,到了后端若没有任何对参数的处理就是这样的:
sql = "select * from user where username='吴君如' and pass='' or '1'='1' "
这条sql一眼就发现问题了吧,它永远能查询到结果,我可以通过这种方式随意登录任意一个账户。
删除数据库表,只需输入';drop table user #
sql = "select * from user where username='吴君如' and pass=''; drop table user #' "
#在sql语句中被视为注释符,后面的语句将被忽略。
SQL注入的防范
经过网络技术不断发着,开发者的安全意识都有不断提高,通过上面介绍这种简单的这种注入方式不再奏效。但hack技术也在不断发展,如果你对SQL注入很感兴趣,你可以关注SQL注入攻击与防御这本书。
现在说说有哪些防范方案:
- 最常见也是最实用的方案,对拼接后的sql语句进行转义,消除外部注入的SQL字符对sql语句产生干扰(如单引号、井号、反斜杠、分号等)。转义可以使用不同开发语言提供的方法,如
- 1 Java可使用预编译语句,Java中有一个PreparedStatement接口,来自java.sql
1. 2 使用ORM框架,不同开发语言都有提供。它会在发送到数据库前对sql语句转义。
2. 避免密码明文存放。即对存储的密码进行单向hash,常用的是MD5摘要算法,它会将输入的密码计算成128位即32个字符。即使被“脱裤”,攻击者也无法拿到用户密码,看到的只是MD5后密码信息。但随着技术的不断发展,一种彩虹表的破解方法迅速流行起来,它存放的是大量的常见明文密码与对应MD5值信息,对被攻击的网站脱裤后,使用彩虹表进行碰撞攻击,就可以快速的破解一部分账户的密码信息。这个时候就需要用到哈希加盐法,这个也很简单,举个栗子,比如用户密码是123,那么MD5(123+dadnqnqnfnoef)之后的值还会简单易辩吗?只需要在系统中定义一个复杂的字符串常量,每次哈希时混入就行了。
3. 处理好异常。避免sql执行错误的异常信息返回到前端,比如数据库版本,服务器版本,编程语言信息,这会给攻击者提供帮助。这个是比较基本的开发注意事项,因为sql执行错误的信息无论如何也不至于在前端输出,应该是在后台日志记录,前端只需要返回错误就行了。