原创:JSP超强Filter,在提交表单中防止注入攻击+过滤HTML标签+过滤javascript

 

转载请注明转载自:http://hi.baidu.com/liheyuan87/

SQL注入已经延伸到了JSP……所以我们必须提高警惕,本类可以对表单提交数据中(POST)的注入攻击做有效的防范,也可以对部分Get中的攻击做防范。并且自动过滤html标签和js代码。自动解决mysql入库时候单引号,双引号导致SQL语句出错的问题。

OK。切入正文。

现来使用方法
1、把类拷贝到filters包下
2、在web.xml中添加FIlter定义和映射,注意,建议把本Filter放在所有Filter的最后
3、web.xml定义如下
    <filter>
        <description>解决SQL注入问题</description>
        <filter-name>SQLInjectionFilter</filter-name>
        <filter-class>filters.SQLInjectionFilter</filter-class>
        <init-param>
            <description>要被过滤掉的字符列表,空格分开</description>
            <param-name>delete</param-name>
            <param-value>and exec insert select delete update count chr mid master truncate char declare</param-value>
        </init-param>
        <init-param>
            <description>要过滤的表单参数名,用空格分开,不在本列表中的参数将不被过滤,以提高效率</description>
            <param-name>param</param-name>
            <param-value>tag content</param-value>
        </init-param>
        </filter>

这里要说明的是,两个Filter预设参数
1、delete:所有要过滤的词,您可以自行添加,注意用空格分开。
2、param:因为只有对于部分参数我们才有必要过滤,所以,在这里指定要过滤的参数名,用空格分开,例如:user pass content title
3、您可以继续添加其他的过滤词汇作为参数,参数名是待替换词汇,参数值是被替换词汇。

映射没什么好说的。。
    <filter-mapping>
        <filter-name>SQLInjectionFilter</filter-name>
        <url-pattern>/poststore</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

转载请注明转载自:http://hi.baidu.com/liheyuan87/

源代码:SQLInjectionFilter.java

package filters;

import java.io.*;
import java.net.*;
import java.util.*;
import java.text.*;
import javax.servlet.*;
import javax.servlet.http.*;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
* 过滤提交表单中的有安全隐患的字符串,以防止SQL注入
* 使用方法:在Filter映射中加入2个参数
* 参数1:delete,用于指定被过滤掉的词汇,用空格分开,例如:delete insert
* 参数2:需要过滤的表单参数名,用空格分开,例如:user pass
* @author lhy
* @version 1.0
*/
public class SQLInjectionFilter implements Filter {

    // The filter configuration object we are associated with. If
    // this value is null, this filter instance is not currently
    // configured.
    private FilterConfig filterConfig = null;
    private static LinkedList<Pair> wordMap = null;
    private static HashSet<String> paramSet = null;
   
    public SQLInjectionFilter() {
    }

    //从Servlet参数中读取Words替换规则并存入wordMap中
    private void doBeforeProcessing(ServletRequest request, ServletResponse response)
    throws IOException, ServletException {
       
        if(wordMap==null || paramSet==null)
        {
            wordMap = new LinkedList<Pair>();
            paramSet = new HashSet();
            Enumeration enums = filterConfig.getInitParameterNames();
            while(enums.hasMoreElements())
            {
                String key = (String)enums.nextElement();
                String value = filterConfig.getInitParameter(key);
                if(key.equals("delete"))
                {
                    for(String s:value.split(" "))
                    {
                        wordMap.add(new Pair(s, ""));
                    }
                }
                else if(key.equals("param"))
                {
                    for(String s:value.split(" "))
                    {
                        paramSet.add(s);
                    }
                }
                else
                {
                   wordMap.add(new Pair(key, value));
                   key = null;
                   value = null;
                }

            }
           
            //其他不好在Filter中过滤的符号,也可以顺便解决数据库入库时候的非法符号
            wordMap.add(new Pair("\"", "&quot; "));//双引号
            wordMap.add(new Pair("\'", "''"));//单引号用''替代
            wordMap.add(new Pair("&", "&amp; "));//&
            wordMap.add(new Pair("<[^>]*>", ""));//超级无敌的正则……替换掉所有的HTML和JS、CSS标签
        }
   
    }

    private void doAfterProcessing(ServletRequest request, ServletResponse response)
    throws IOException, ServletException {
    //
    // Write code here to process the request and/or response after
    // the rest of the filter chain is invoked.
    //
   
    //
    // For example, a logging filter might log the attributes on the
    // request object after the request has been processed.
    //
    /*
    for (Enumeration en = request.getAttributeNames(); en.hasMoreElements(); ) {
        String name = (String)en.nextElement();
        Object value = request.getAttribute(name);
        log("attribute: " + name + "=" + value.toString());

    }
    */
    //

    //
    // For example, a filter might append something to the response.
    //
    /*
    PrintWriter respOut = new PrintWriter(response.getWriter());
    respOut.println("<P><B>This has been appended by an intrusive filter.</B>");
    */
    }

    /**
     *
     * @param request The servlet request we are processing
     * @param response The servlet response we are creating
     * @param chain The filter chain we are processing
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet error occurs
     */
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain)
    throws IOException, ServletException {

    doBeforeProcessing(request, response);
   
    Throwable problem = null;

    try
        {
            request = new NewWrapper((HttpServletRequest)request,wordMap,paramSet);

        chain.doFilter(request, response);
    }
    catch(Throwable t) {
        //
        // If an exception is thrown somewhere down the filter chain,
        // we still want to execute our after processing, and then
        // rethrow the problem after that.
        //
        problem = t;
        t.printStackTrace();
    }

    doAfterProcessing(request, response);

    //
    // If there was a problem, we want to rethrow it if it is
    // a known type, otherwise log it.
    //
    if (problem != null) {
        if (problem instanceof ServletException) throw (ServletException)problem;
        if (problem instanceof IOException) throw (IOException)problem;
        sendProcessingError(problem, response);
    }
    }

   
    /**
     * Return the filter configuration object for this filter.
     */
    public FilterConfig getFilterConfig() {
    return (this.filterConfig);
    }

    /**
     * Set the filter configuration object for this filter.
     *
     * @param filterConfig The filter configuration object
     */
    public void setFilterConfig(FilterConfig filterConfig) {

    this.filterConfig = filterConfig;
    }

    /**
     * Destroy method for this filter
     *
     */
    public void destroy() {
    }

    /**
     * Init method for this filter
     *
     */
    public void init(FilterConfig filterConfig) {

    this.filterConfig = filterConfig;
    }

    /**
     * Return a String representation of this object.
     */
    public String toString() {

    if (filterConfig == null) return ("SQLInjectionFilter()");
    StringBuffer sb = new StringBuffer("SQLInjectionFilter(");
    sb.append(filterConfig);
    sb.append(")");
    return (sb.toString());

    }

    private void sendProcessingError(Throwable t, ServletResponse response) {
   
    String stackTrace = getStackTrace(t);

    if(stackTrace != null && !stackTrace.equals("")) {

        try {
           
        response.setContentType("text/html");
        PrintStream ps = new PrintStream(response.getOutputStream());
        PrintWriter pw = new PrintWriter(ps);
        pw.print("<html>\n<head>\n<title>Error</title>\n</head>\n<body>\n"); //NOI18N
           
        // PENDING! Localize this for next official release
        pw.print("<h1>The resource did not process correctly</h1>\n<pre>\n");
        pw.print(stackTrace);
        pw.print("</pre></body>\n</html>"); //NOI18N
        pw.close();
        ps.close();
        response.getOutputStream().close();;
        }
       
        catch(Exception ex){ }
    }
    else {
        try {
        PrintStream ps = new PrintStream(response.getOutputStream());
        t.printStackTrace(ps);
        ps.close();
        response.getOutputStream().close();;
        }
        catch(Exception ex){ }
    }
    }

    public static String getStackTrace(Throwable t) {

    String stackTrace = null;
       
    try {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        t.printStackTrace(pw);
        pw.close();
        sw.close();
        stackTrace = sw.getBuffer().toString();
    }
    catch(Exception ex) {}
    return stackTrace;
    }

    public void log(String msg) {
    filterConfig.getServletContext().log(msg);
    }

     public static void main(String args[])
    {
         String str="select";
    }
}

class Pair
{
    public String key;
    public String value;
   
    public Pair(String k,String v)
    {
        key = k;
        value = v;
    }
}

class NewWrapper extends HttpServletRequestWrapper
{
    private LinkedList<Pair> wordMap;
    private HashSet<String> paramMap;
   
    public NewWrapper(HttpServletRequest req,LinkedList<Pair> map,HashSet m2)
    {
        super(req);
        wordMap = map;
        paramMap = m2;
    }
    public String getParameter(String str)
    {
        try
        {
            String param = super.getParameter(str);
           
            if(!paramMap.contains(str))
            {
                //如果不包含在被过滤列表中,直接返回
                return param;
            }
           
            Iterator<Pair> itr = wordMap.listIterator();
            while(itr.hasNext())
            {
                Pair p = itr.next();
               
                param = param.replaceAll(p.key, p.value);
            }
            return param.trim();
        }
        catch (Exception e)
        {
            return null;
        }

    }
   

}

转载请注明转载自:http://hi.baidu.com/liheyuan87/
学JSP不到2周,不当之处请大家多多指教。

One thought on “原创:JSP超强Filter,在提交表单中防止注入攻击+过滤HTML标签+过滤javascript

Leave a Reply

Your email address will not be published.