春风博客

春天里,百花香...

导航

<2008年10月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

统计

公告

MAIL: junglesong@gmail.com
MSN: junglesong_5@hotmail.com

Locations of visitors to this page

常用链接

留言簿(11)

随笔分类(224)

随笔档案(126)

个人软件下载

我的其它博客

我的邻居们

最新随笔

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜

SQL注入攻击及其防范浅谈

SQL注入攻击
SQL注入攻击的基本原理,是从客户端合法接口提交特殊的非法代码,让其注入到服务器端执行业务的SQL中去,进而改变SQL语句的原有逻辑和影响服务器端正常业务的处理。
SQL注入攻击是Web应用中一个重要的安全问题,虽然Java具备较高的安全性,但如果开发人员不注意,也有可能留下安全隐患,请看示例:

执行验证的SQL语句
现有一个Login页面用来控制WebApp的入口,用户想要进入只有输入“用户名”和“密码”,负责用户登录处理的Servlet接受到请求后,将看数据表usertable中是否存在这个用户名和密码,如果存在则让其进入,否则拒绝,进行验证的SQL语句如下:

select count(*from usertable where name='用户名' and pswd='密码‘

执行完这条SQL语句后,如果记录数等于零说明在usertable表找不到用户名和密码对应的记录,应该拒绝;如果记录数大于零则说明能在usertable表中找到对应的记录,应予放行。

如果用户进行SQL注入则可使验证无效

如果用户通过某种途径知道或是猜测出了验证SQL语句的逻辑,他就有可能在表单中输入特殊字符改变SQL原有的逻辑,比如在名称文本框中输入“ ‘ or ’1‘=’1‘ or ’1‘=’1 ”或是在密码文本框中输入“ 1‘ or ’1‘=’1 ”,SQL语句将会变成:

1select count(*from usertable where name='' or '1'='1' or '1'='' and pswd='' 
2select count(*from usertable where name='' and pswd='1' or '1'='1' 

明显,or和单引号的加入使得where后的条件始终是true原有的验证完全无效了。

使用正则表达式屏蔽特殊字符

使用SQL注入攻击多在特殊字符上下手脚,如“’”,“*”,“/” ,”--”等,如果用正则表达式限制特殊字符输入,这些手段将没有效果。下面的代码将阻止含有特殊字符的请求。

if(Pattern.matches("\\w+", name)==false || Pattern.matches("\\w+", pswd)==false ){
  
// 返回login界面
  request.setAttribute("feedbackMsg""用户名和密码不允许包括特殊字符");
  RequestDispatcher dispatcher 
= request.getRequestDispatcher("/web/page/login1.jsp?curr=0");
  dispatcher.forward(request, response);
  
return;
}

使用PreparedStatement代替Statement

SQL注入攻击能得逞是因为在原有SQL语句中加入了新的逻辑,如果使用PreparedStatement执行SQL语句,其后只是输入参数, SQL注入攻击手段将无效,这是因为PreparedStatement不允许在不同的插入时间改变查询的逻辑结构。示例代码如下:

Connection conn=null;
PreparedStatement ps
=null
ResultSet rs
=null;

String sql
=" select count(*) from usertable where name=? and pswd=? ";
ps
=conn.prepareStatement(sql);
ps.setString(
1, name);
ps.setString(
2, pswd);

PreparedStatement的错误使用

用PreparedStatement来防范SQL注入攻击是因为“因为PreparedStatement不允许在不同的插入时间改变查询的逻辑结构”,如果如下使用则起不到这个效果,因为SQL语句和参数没有分开,它们被组合在一起被一次性提交了。

Connection conn=null;
PreparedStatement ps
=null
ResultSet rs
=null;

。。。。
conn
=DBUtil.getConnection(); 
sql
=" select count(*) from usertable where name='"+name+"' and pswd='"+pswd+"";
ps
=conn.prepareStatement(sql);   
rs
=ps.executeQuery();

这种情况下要防范SQL注入攻击还是要借助于正则表达式

小结

1.Web系统通常采用数据库作为数据源,而大多数业务处理都离不开SQL语句,因此系统潜在就有被SQL注入攻击的隐患,攻击可能会从任何一次URL提交或是FORM提交中发起。
2.使用PreparedStatement执行Sql语句比Statement安全得多,如果能使用PreparedStatement就不该用Statement,当然SQL主体和参数应该分开。
3.如果因为要执行动态多变的SQL语句而不得已采用Statement,则应该在服务器端用正则表达式进行输入验证。
4.客户端验证可能被取消,因此服务器端验证必不可少。

示例代码:
http://www.blogjava.net/Files/sitinspring/SQLInjection20081011195750.rar

posted on 2008-10-11 19:52 sitinspring 阅读(9764) 评论(3)  编辑  收藏 所属分类: Java APIDB&SQL

评论

# re: SQL注入攻击及其防范浅谈 2008-10-11 20:46 日月雨林@gmail.com

很不错的文章,看来我以后要多注意细节问题了!  回复  更多评论   

# re: SQL注入攻击及其防范浅谈 2014-11-28 13:03 22222222222222222222222222222222222222222222222222

33333  回复  更多评论   

# re: SQL注入攻击及其防范浅谈 2016-04-02 19:40 ‘ or ’1‘=’1‘ or ’1‘=’1

‘ or ’1‘=’1‘ or ’1‘=’1   回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
sitinspring(http://www.blogjava.net)原创,转载请注明出处.