SQL注入,通过把SQL命令插入到Web表单或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。
SQL是一种用于管理数据库的查询语言。使用它可以增删改查存储在数据库中的数据,在某些情况下你甚至可以使用SQL命令去执行一些操作系统命令,因此一个成功的SQL注入可以引起非常严重的后果。
SQL注入可能造成的一些后果:
- 攻击者可以使用SQL注入得到其他用户的数据库凭证,然后他们能模仿这些数据库用户。
- 攻击者可以使用SQL注入从数据库中选择并输出数据
- 攻击者可以是使用SQL注入改变、增加、删除数据,甚至删除数据表。
- 在一些数据库中,你可以使用数据库系统访问操作系统。
SQL注入的一些例子:
1. 拼接SQL:
# Define POST variables
uname = request.POST['username']
passwd = request.POST['password']
# SQL query vulnerable to SQLi
sql = “SELECT id FROM users WHERE username=’” + uname + “’ AND password=’” + passwd + “’”
# Execute the SQL statement
database.execute(sql)
用户可以传入一个单引号,设置password字段值为:
password' OR 1=1
用户也可以添加注释使SQL 语句忽略掉后面的查询条件
2. 基于union的SQL注入
GET http://testphp.vulnweb.com/artists.php?artist=1 HTTP/1.1
Host: testphp.vulnweb.com
GET http://testphp.vulnweb.com/artists.php?artist=-1 UNION SELECT 1,pass,cc FROM users WHERE uname='test' HTTP/1.1
Host: testphp.vulnweb.com
SQL 注入预防
对于后端程序员,我感觉不使用动态拼接SQL,使用参数化SQL就可以达到了。一些ORM也是采用的此种方式,比如Django。如果有能在参数化SQL中实现SQL注入的方式请告知,非常感谢
参数化SQL:
在使用参数化查询的情况下,数据库服务器不会将参数的内容视为SQL指令的一部份来处理,而是在数据库完成 SQL指令的编译后,才套用参数运行,因此就算参数中含有恶意的指令,由于已经编译完成,就不会被数据库所运行。
一些其他的防护
- 永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。(我感觉一般是DBA的工作,他们给啥类型的用户我们也就只能用啥)
- 不要把机密信息直接存放,加密或者hash掉密码和敏感的信息。(主要防止数据库被连接或注入成功后得到该类信息)
- 给用户展示的应用的异常信息,不应该是数据库的返回,或者程序的异常信息,应该根据异常类别给出提示信息。(暴露越少的应用信息对于程序越安全,对用户的体验也越少,他们可能不懂)
网友评论