struts2拦截器来防止sql注入

SQL注入攻击能得逞是因为在原有SQL语句中加入了新的逻辑

比如:原sql="select * from user where userid='"+userid+"'";

如果,我们把userid="' or 1='1";

这样拼接的sql="select * from user where userid='' or 1='1'";

这样的sql就可列出表里的所有记录

对于一个好的程序员来说,编写高质量的代码,可以防止sql注入

比如使,用PreparedStatement来代替Statement来执行SQL语句,其后只是输入参数

SQL注入攻击手段将无效,这是因为PreparedStatement不允许在不同的插入时间改变查询的逻辑结构 

大部分的SQL注入已经挡住了

有时候我们的sql语句是拼接,这样如果再重构我们的数据库操作的话,会很麻烦的

为此我们需要对表单中的非法字符进行过滤

当然,我们可以用Filter来实现,对提交到servlet的表单进行验证

但是,对于Struts2框架来说,似乎不起作用

这就需要用到struts2的拦截器来实现同样的功能

拦截器使用就不再介绍,网上很多

现在就我的实现代码贴出来供大家参考

IllegalCharacterInterceptor.java

import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.util.ValueStack;
import com.sun.imageio.plugins.common.I18N;

public class IllegalCharacterInterceptor extends AbstractInterceptor {

 @Override
 public String intercept(ActionInvocation invocation) throws Exception {
  //通过核心调度器invocation来获得调度的Action上下文
  ActionContext actionContext = invocation.getInvocationContext();
  //获取Action上下文的值栈
  ValueStack stack = actionContext.getValueStack();
  //获取上下文的请求参数
  Map valueTreeMap = actionContext.getParameters();
  //获得请求参数集合的迭代器
  Iterator iterator = valueTreeMap.entrySet().iterator();
  //遍历组装请求参数
  while(iterator.hasNext()){
   //获得迭代的键值对
   Entry entry = (Entry) iterator.next();
   //获得键值对中的键值
   String key = (String) entry.getKey();
   //原请求参数,因为有可能一键对多值所以这里用的String[]
   String[] oldValues = null;
   //对参数值转换成String类型的
   if(entry.getValue() instanceof String){
    oldValues = new String[]{entry.getValue().toString()};
   }else{
    oldValues = (String[])entry.getValue();
   }
   //处理后的请求参数
   String newValueStr = null;
   //对请求参数过滤处理
   if(oldValues.length>1){
    newValueStr = "{" ;
    for(int i=0 ;i<oldValues.length; i++){
     //替换掉非法参数,这里只替换掉了',如有其他需求,可以专门写一个处理字符的类
     newValueStr+=oldValues[i].toString().replaceAll("'","");
     if(i!=oldValues.length-1){
      newValueStr+=",";
     }
    }
    newValueStr+="}";
   }else if(oldValues.length==1){
    //替换掉非法参数,这里只替换掉了',如有其他需求,可以专门写一个处理字符的类
    newValueStr = oldValues[i].toString().replaceAll("'","");

   }else{
    newValueStr = null;
   }
   //处理后的请求参数加入值栈中
   stack.setValue(key, newValueStr);
  }
  String result = null;
  try {
   // 调用下一个拦截器,如果拦截器不存在,则执行Action 
   result = invocation.invoke();
  } catch (Exception e) {
   e.printStackTrace();
  }
  return result;
 }

}

拦截器写好后,就可以使用了

在struts.xml中配置自定义拦截器时,需把默认拦截器加上

不然默认拦截器会不起作用的

<interceptors>
    <interceptor name="illegalCharacter" class="com.ainong.interceptor.IllegalCharacterInterceptor"/>
    <interceptor-stack name="myStack">
     <interceptor-ref name="defaultStack"></interceptor-ref>
     <interceptor-ref name="illegalCharacter"></interceptor-ref>
    </interceptor-stack>
   </interceptors>

这样就可使用myStack来拦截了

如果我们对于对每个Action都配置<interceptor-ref name="myStack"/>比较麻烦

我们也可把上面的拦截器栈,设置为默认拦截器栈,这样可以对package中的所有Action起作用

而不需要我们配置

<default-interceptor-ref name="myStack"></default-interceptor-ref>

posted @ 2013-05-15 18:22  七星6609  阅读(7626)  评论(0编辑  收藏  举报