sql注入解释

sql注入例子,假设DB中存在如下数据:
+----+---------+----------+
| id | uid     | password |
+----+---------+----------+
|  1 | forrest  | abc      |
|  3 | denny   | abc      |
|  5 | peggy   | abc      |
|  6 | vivian   | abc      |
+----+---------+----------+
正常Query语句:SELECT * FROM user WHERE uid='vivian' AND password='abc';
用户名框注入:'123' OR '1'='1',密码框输入:'abc' --> sql语句变为:SELECT * FROM user WHERE (uid='123' OR '1'='1') AND (password='abc');
 可查询到所有密码为abc的用户,并登陆成功。
密码框注入:'123' OR '1'='1',用户名框输入:'vivian' --> sql语句变为:SELECT * FROM user WHERE (uid='vivian' AND password='123') OR ('1'='1');
 可查询到所有用户,并登陆成功。
用户名框注入:'123' OR '1'='1',密码框注入:'123' OR '1'='1' --> sql语句变为:SELECT * FROM user WHERE [(uid='123' OR '1'='1') AND password='123'] OR '1'='1';
 可查询到所有用户,并登陆成功(可以看出结果和只在密码框中注入sql的结果是一样的)。
上面中的()[]是为了给sql断句,以便理解(这样就应该很好理解了吧,一个很简单的逻辑哦,我就不解释了)。实际应用中并无此类括号。

ps:如果知道了DB中某Table的tablename。则可以对其进行破坏,eg密码框注入:'123'; drop table tb_name; --> 真的很发指啊!!!

 

1、PreparedStatement
可对sql预编译. 你传入的任何内容就不会和原来的语句发生任何匹配的关系(前提是数据库本身支持预编译,但目前流行数据库都支持预编译了)
2、表单验证(正则表达式)对数据进行过滤(屏蔽掉注入关键词)
3、正则表达式检测已经形成的sql语句(在sql被execute前进行)

    2.1、检测SQL meta-characters的正则表达式    /(\%27)|(\')|(\-\-)|(\%23)|(#)/ix
    2.2、修正检测SQL meta-characters的正则表达式 /((\%3D)|(=))[^\n]*((\%27)|(\')|(\-\-)|(\%3B)|(:))/i
    2.3、典型的SQL注入攻击的正则表达式 /\w*((\%27)|(\'))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix
    2.4、检测SQL注入,UNION查询关键字的正则表达式 /((\%27)|(\'))union/ix(\%27)|(\') - 单引号和它的hex等值union - union关键字。
    2.5、检测MS SQL Server SQL注入攻击的正则表达式 /exec(\s|\+)+(s|x)p\w+/ix
4、Filter过滤

public static String filterContent(String content){
     String flt ="'|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";
     String filter[] = flt.split("|");
     for(int i=0;i<filter.length ; i++){
         content.replace(filter[i], "");
     }
     return content;
}

5、 避免动态SQL
动态SQL是动态查询的很好的工具,但这也会暴露脆弱点。很多情况下可以使用其他SQL语句或存储过程来代替动态SQL。当然,如果您在存储过程中依然通过用户输入来建立动态SQL查询,那么只靠替换还是不安全的。

6、最低权限原则
永远也不要在代码中用管理员级别权限的帐户来连接数据库。应用程序使用的帐户应该只拥有应用程序需要的最低级别的权限。这也能将已入侵者造成的破坏降低到最低限度。应用程序不能已sa或其他管理员帐号连接数据库,而且应定义使用的帐号能访问的范围。

7. 安全存储机密信息
不要用明文存储机密信息。较好的替代方法是使用加密或散列密码。散列密码较加密密码更安全,这是因为它们不能被解密。你还可以在散列加密之前添加一些随机值来增加安全性。

8. 只有知道如何注入,才能更有效的防注。一个例子
正常地址:
http://www.xxx.com/news.asp?id=1

加个',如果没过滤特殊字符,网页一定出错,就是看怎么出错法。画面能显示一部分,一部分提示数据库出错,找不到什么什么,最有希望注入。
http://www.xxx.com/news.asp?id=1'

下一步,试试 and 1=1 ,如果画面不出错,1=1是成立的,有希望了。
http://www.xxx.com/news.asp?id=1 and 1=1

下一步,试试 and 1=2 ,如果画面出错,1=2是不成立的,可以肯定这个地址可以注入。
http://www.xxx.com/news.asp?id=1 and 1=2

好戏来了:
http://www.xxx.com/news.asp?id=1 and (select * from admin)>0
不出错,证明数据库有admin这个表。

http://www.xxx.com/news.asp?id=1 and (select username from admin)>0
不出错,证明数据库的admin有username这个字段。

http://www.xxx.com/news.asp?id=1 and len(select top 1 username from admin)>5
不出错,证明数据库的admin的第一个username长度>5。

后面的自己测试……本文的目的仅用于各位站长检测自己的站有没有SQL注入漏洞。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值