SQL注入是什么,怎么防止SQL注入?

什么是SQL注入?


SQL 注入就是在用户输入的字符串中加入 SQL 语句,如果在设计程序中忽略了检查,那么这些注入进去的 SQL 语句就会被数据库服务器误认为是正常的 SQL 语句而运行,通过SQL语句,实现无帐号登录,甚至篡改数据库。

SQL注入总体思路


1、寻找到SQL注入的位置
2、判断服务器类型和后台数据库类型
3、针对不通的服务器和数据库特点进行SQL注入攻击

下面使用登录来进行测试
点击登陆,如果没有做特殊处理,非法用户就很容易登陆进去了。

例如:后台程序中使用的SQL语句为:

String sql="select * from user where username='"+userName+"’and password='"+password+” '”;


当输入了下面的用户名和密码,上面的SQL语句变成:

SELECT * FROM user WHERE username='1’or 1=1 # and password=''


条件后面username=‘1’ or 1=1 然后后面加#将后面的语句注释,让他们不起作用,这样语句就是为真了,用户能轻易骗过系统,获取合法身份。SQL注入还可以用来删除、添加、修改数据库中的记录等等

SQL注入的原理

SQL 注入的原理主要有以下 4 点:
1)恶意拼接查询
我们知道,SQL 语句可以查询、插入、更新和删除数据,且使用分号来分隔不同的命令。例如:

SELECT * FROM users WHERE user_id = $user_id


其中,user_id 是传入的参数,如果传入的参数值为“1234; DELETE FROM users”,那么最终的查询语句会变为:

SELECT * FROM users WHERE user_id = 1234; DELETE FROM users


如果以上语句执行,则会删除 users 表中的所有数据。
2)利用注释执行非法命令
SQL 语句中可以插入注释。例如:

SELECT COUNT(*) AS ‘num’ FROM game_score WHERE game_id=24411 AND version=$version


如果 version 包含了恶意的字符串’-1’ OR 3 AND SLEEP(500)–,那么最终查询语句会变为:

SELECT COUNT(*) AS ‘num’ FROM game_score WHERE game_id=24411 AND version=‘-1’ OR 3 AND SLEEP(500)–


以上恶意查询只是想耗尽系统资源,SLEEP(500) 将导致 SQL 语句一直运行。如果其中添加了修改、删除数据的恶意指令,那么将会造成更大的破坏。
3)传入非法参数
SQL 语句中传入的字符串参数是用单引号引起来的,如果字符串本身包含单引号而没有被处理,那么可能会篡改原本 SQL 语句的作用。 例如:

SELECT * FROM user_name WHERE user_name = $user_name


如果 user_name 传入参数值为s'a,那么最终的查询语句会变为:

SELECT * FROM user_name WHERE user_name =‘G’chen’


一般情况下,以上语句会执行出错,这样的语句风险比较小。虽然没有语法错误,但可能会恶意产生 SQL 语句,并且以一种你不期望的方式运行。
4)添加额外条件
在 SQL 语句中添加一些额外条件,以此来改变执行行为。条件一般为真值表达式。例如:

UPDATE users SET userpass='u s e r p a s s ′ W H E R E u s e r i d = userpass' WHERE user_id=userpass′WHEREuseri​d=user_id;


如果 user_id 被传入恶意的字符串“1234 OR TRUE”,那么最终的 SQL 语句会变为:

UPDATE users SET userpass= ‘123456’ WHERE user_id=1234 OR TRUE;


这将更改所有用户的密码。

避免SQL注入

尽量不要使用SQL语句直接拼接。
如果用SQL语句,尽可能使用参数化,添加Param。
尽可能的使用存储过程,安全性能高而且处理速度也快。

严格限制 Web 应用的数据库的操作权限,给连接数据库的用户提供满足需要的最低权限,最大限度的减少注入攻击对数据库的危害
校验参数的数据格式是否合法(可以使用正则或特殊字符的判断)
对进入数据库的特殊字符进行转义处理,或编码转换

对进入数据库的特殊字符('"\尖括号&*;等)进行转义处理,或编码转换。

所有的查询语句建议使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到SQL语句中,即不要直接拼接SQL语句。

预编译 SQL(Java 中使用 PreparedStatement),参数化查询方式,避免 SQL 拼接
报错信息不要包含 SQL 信息输出到 Web 页面

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值