WEB程序防SQL注入攻击程序

场景: WEB程序容易被SQL注入攻击,攻击原理是在请求参数中传入非法字符,造成SQL语句出现出现异常情况,已达到攻击者想要的结果。

分析: 一般的攻击者都是在传入的请求参数上做文章,所以我们重点检查的是request的参数,判断request请求参数是否有非法字符,及数据库关键字,如果有即判定为SQL注入,否则通过。一般在WEB应用中都采用FILTER技术来处理此类问题,以下类适用于ORACLE,其他数据库请修改SqlInjectFilter类中的static{ }内的关键字。

新增功能: 验证POST攻击,精简验证列表,优化验证框架

解决:

1. 配置FILTER,配置位置为 /WEB-INF/web.xml

 
       SqlInjectFilter
      SqlInjectFilter
     
          enabled
           true
      

      
          failthPath
           /failth.jsp
      

   

   
       SqlInjectFilter
       *.jsp
   

   
       SqlInjectFilter
       *.do
   

 

说明:

    1. SqlInjectFilter 为类全路径,可以根据具体情况修改

    2.  这里判定是否启用,默认是启用,否则将  true 修改为  false

      
          enabled
           true
      

    3. 这是判定SQL注入后跳转的页面,根据实际情况修改 /failth.jsp 中的 /failth.jsp

      
          failthPath
           /failth.jsp
      


 

2. 新建FILTER类: SqlInjectFilter ; 2. 配置FILTER

 

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.Vector;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 *
* @ClassName: SqlInjectFilter
* @Description: TODO V2.0
* @author fasake [email protected]
* @date 2012-12-20 下午8:53:34
*
 */
public class SqlInjectFilter implements Filter {
 protected Log log = LogFactory.getLog(getClass());
 protected static Vector list = new Vector();
 protected String enabled = "true";
 protected String failthPath = "/TaxWeb/failth.jsp";

 public void destroy() {
  // TODO Auto-generated method stub

 }

 public void doFilter(ServletRequest arg0, ServletResponse arg1,
   FilterChain arg2) throws IOException, ServletException {
  // TODO Auto-generated method stub
  HttpServletRequest httpServletRequest = (HttpServletRequest) arg0;
  HttpServletResponse httpServletResponse = (HttpServletResponse) arg1;
  //获取GET方法请求参数串
  String queryString = httpServletRequest.getQueryString();
  
        //是否启动,web.xml中配置的初始化参数
  if (enabled.equalsIgnoreCase("true")) {
   //开始XSS(METHOD:GET)和sql注入检测
   boolean isXssFind = false;
   if(queryString!=null && !queryString.equalsIgnoreCase("null")){
    String src = java.net.URLDecoder.decode(queryString,"GB2312");
    src  += "_"+queryString;
    if(src!=null && !src.equalsIgnoreCase("null")){
     String keyword = "";
     for (int i = 0; i < list.size(); i++) {
       keyword = list.get(i).toString();
       if(src.indexOf(keyword)!=-1){
        isXssFind = true;
        break;
       }
     }
     if(isXssFind){
      log.error("发现疑为跨站脚本攻击,检测判断请求地址包含非法字符:"+java.net.URLEncoder.encode(keyword,"GB2312"));
      httpServletRequest.setAttribute("errorMsg", "发现疑为跨站脚本攻击,检测判断请求地址包含非法字符:"+java.net.URLEncoder.encode(keyword,"GB2312"));
      httpServletRequest.getSession(true).setAttribute("injectKey","发现疑为跨站脚本攻击,检测判断请求地址包含非法字符:"+java.net.URLEncoder.encode(keyword,"GB2312"));
      httpServletRequest.getSession().invalidate();
      httpServletResponse.sendRedirect(failthPath);
       throw new java.lang.IllegalAccessError();
     }
    }
   }
   //开始XSS(METHOD:POST)和sql注入检测
   if(!isXssFind){
    arg2.doFilter(new RequestWrapperXSS(httpServletRequest,httpServletResponse,list,failthPath), arg1);
   }
  }else{
   arg2.doFilter(arg0, arg1);
  }

 }

 
 /**
  * 初始化
  */
 public void init(FilterConfig arg0) throws ServletException {
  // TODO Auto-generated method stub

  enabled = arg0.getInitParameter("enabled");
  failthPath = arg0.getInitParameter("failthPath");
  if (enabled == null || "".equals(enabled)) {
   enabled = "true";
  }
  if (failthPath == null || "".equals(failthPath)) {
   enabled = "/TaxWeb/failth.jsp";
  }
  log.info("SQL注入检测初始化完成");
 }

 static {
  list.add("'");
  list.add("(");
  //list.add("or");
  //list.add("and");
  list.add("[");
  list.add("<");
  list.add(".."+File.separator);
  // 请求参数不能能有脚步
  list.add("script");
  list.add("+");
  //list.add("-");
  list.add("*");
  list.add("%");
 }
}

/**
 *
* @ClassName: RequestWrapperXSS
* @Description: TODO 自定义HttpServletRequest
* @author fasake [email protected]
* @date 2012-12-20 下午7:16:00
*
 */
class RequestWrapperXSS extends HttpServletRequestWrapper {
 protected Log log = LogFactory.getLog(getClass());
 private HttpServletRequest request;
 private HttpServletResponse serlvetResponse;
 private boolean isXssFind=false;
 private Vector keywords;
 private String failForwardPath;
 public RequestWrapperXSS(HttpServletRequest servletRequest) {
  super(servletRequest);
  this.request = servletRequest;
 }
 /**
  *
  * @param servletRequest
  * @param serlvetResponse
  */
 public RequestWrapperXSS(HttpServletRequest servletRequest,HttpServletResponse serlvetResponse) {
  super(servletRequest);
  this.request = servletRequest;
  this.serlvetResponse = serlvetResponse;
 }
 public RequestWrapperXSS(HttpServletRequest servletRequest,HttpServletResponse serlvetResponse,Vector keywords,String failForwardPath) {
  super(servletRequest);
  this.request = servletRequest;
  this.serlvetResponse = serlvetResponse;
  this.keywords = keywords;
  this.failForwardPath = failForwardPath;
 }
 /**
  * 覆盖
  */
 public String[] getParameterValues(String name){
  String[] values = super.getParameterValues(name);
  //log.debug("parameter name: "+name+" value:"+values.toString());
  try {
   xssCheck(values,keywords);
  } catch (IllegalAccessError e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   throw e;
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  return values;
 }
 /**
  * 覆盖
  */
 public String getParameter(String para){
  String postStrInfo = super.getParameter(para);
  //log.debug("parameter name: "+para+" value:"+postStrInfo);
  try {
   //log.debug("parameter name: "+para);
   log.debug("(检测)接收到的["+request.getMethod()+"]请求参数值: " + postStrInfo); 
   xssCheck(postStrInfo,keywords);
   
   
  } catch (IllegalAccessError e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   throw e;
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  return postStrInfo;
 }
 
  public ServletInputStream getInputStream() {
   //ServletInputStream
   ServletInputStream stream = null; 
   //POST表单信息
   String postStrInfo = null;
    try{
      stream = request.getInputStream();
      byte[] buffer = IOUtils.toByteArray(stream);
      postStrInfo = new String(buffer,"GB2312");
      //拆分请求参数串
      String[] args = postStrInfo.split("\r\n");
      for (int i = 0; i < args.length; i++) {
       String line  = args[i];
       //过滤分隔符,和请求参数名称
       if(line.trim().startsWith("-------------------") || line.trim().startsWith("Content-Disposition")  || line.trim().equals("")){
        log.debug("(忽略)接收到的["+request.getMethod()+"]请求参数值: " + line); 
        continue;
       }
       log.debug("(检测)接收到的["+request.getMethod()+"]请求参数值: " + line); 
       xssCheck(line,keywords);
      }
      
      //验证完成
      final ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
      //生成新的ServletInputStream
      ServletInputStream sis = new ServletInputStream() {
       public int read() throws IOException {
        // TODO Auto-generated method stub
        return bais.read();
       }
      };
      stream = sis;
    }catch(IOException e){
     e.printStackTrace();
    } 
   
   return  stream;
  }
 /**
 * @Title: xssCheck
 * @Description: TODO 检测XSS和SQL注入处理类
 * @param @param postStrInfo
 * @param @throws IOException
 * @param @throws IllegalAccessError
 * @return void
 * @throws
 */
 private void xssCheck(String postStrInfo,Vector array) throws IOException,
   IllegalAccessError {
  if(postStrInfo==null)return;
  String src = postStrInfo==null?"null":postStrInfo.toLowerCase();
  src = java.net.URLDecoder.decode(src,"GB2312");
  //验证XSS中是否包含相关关键字
  if(src!=null && !src.equalsIgnoreCase("null")){
   String keyword = "";
   for (int i = 0; i < array.size(); i++) {
    
     keyword = array.get(i).toString();
     if(src.indexOf(keyword)!=-1){
      isXssFind = true;
      break;
     }
   }
   if(isXssFind){
    log.error("发现疑为跨站脚本攻击,检测判断请求地址包含非法字符:"+java.net.URLEncoder.encode(keyword,"GB2312"));
    request.setAttribute("errorMsg", "发现疑为跨站脚本攻击,检测判断请求地址包含非法字符:"+java.net.URLEncoder.encode(keyword,"GB2312"));
    request.getSession(true).setAttribute("injectKey","发现疑为跨站脚本攻击,检测判断请求地址包含非法字符:"+java.net.URLEncoder.encode(keyword,"GB2312"));
    request.getSession().invalidate();
    serlvetResponse.sendRedirect(failForwardPath);
     throw new java.lang.IllegalAccessError();
   }
  }
 }
 /**
  *
 * @Title: xssCheck
 * @Description: TODO 检测XSS
 * @param @param values
 * @param @param array
 * @param @throws IOException
 * @param @throws IllegalAccessError
 * @return void
 * @throws
  */
 private void xssCheck(String[] values,Vector array) throws IOException,IllegalAccessError {
             if(values==null){return;}
             for (int j = 0; j < values.length; j++) {
    String src = java.net.URLDecoder.decode(values[j],"GB2312");
    //验证XSS中是否包含相关关键字
    if(src!=null && !src.equalsIgnoreCase("null")){
     String keyword = "";
     for (int i = 0; i < array.size(); i++) {
       keyword = array.get(i).toString();
       if(src.indexOf(keyword)!=-1){
        isXssFind = true;
        break;
       }
     }
     if(isXssFind){
      log.error("发现疑为跨站脚本攻击,检测判断请求地址包含非法字符:"+java.net.URLEncoder.encode(keyword,"GB2312"));
      request.setAttribute("errorMsg", "发现疑为跨站脚本攻击,检测判断请求地址包含非法字符:"+java.net.URLEncoder.encode(keyword,"GB2312"));
      request.getSession(true).setAttribute("injectKey","发现疑为跨站脚本攻击,检测判断请求地址包含非法字符:"+java.net.URLEncoder.encode(keyword,"GB2312"));
      request.getSession().invalidate();
      serlvetResponse.sendRedirect(failForwardPath);
       throw new java.lang.IllegalAccessError();     }
    }
   }
    }

你可能感兴趣的:(XSS,WEB安全,XSS,SQL注入,网站安全)