Java Filter防止sql注入攻击
原理,过滤所有请求中含有非法的字符,例如:, & < select delete 等关键字,黑客可以利用这些字符进行注入攻击,原理是后台实现使用拼接字符串,案例:
某个网站的登入验证的SQL查询代码为
strSQL = "SELECT * FROM users WHERE (name = '" + userName + "') and (pw = '"+ passWord +"');"
恶意填入
userName = "' OR '1'='1";与passWord = "' OR '1'='1";时,将导致原本的SQL字符串被填为
strSQL = "SELECT * FROM users WHERE (name = '' OR '1'='1') and (pw = '' OR '1'='1');"
也就是实际上运行的SQL命令会变成下面这样的
strSQL = "SELECT * FROM users;"
因此达到无帐号密码,亦可登入网站。所以SQL注入攻击被俗称为黑客的填空游戏。
实现三个步骤:
1,编写filter
2,配置xml
3,配置error.jsp
filter代码;
package cn.kepu.filter; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Set; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 防止sql注入,自定义filter www.2cto.com * cn.kepu.filter.SqlInjectFilter.java * @author ffr * created at 2012-7-12 */ public class SqlInjectFilter implements Filter { private static List<String> invalidsql = new ArrayList<String>(); private static String error = "/error.jsp"; private static boolean debug = false; public void destroy() { } public void doFilter(ServletRequest req, ServletResponse res, FilterChain fc) throws IOException, ServletException { if(debug){ System.out.println("prevent sql inject filter works"); } HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)res; Map<String, String> params = request.getParameterMap(); Set<String> keys = params.keySet(); for(String key : keys){ String value = request.getParameter(key); if(debug){ System.out.println("process params <key, value>: <"+key+", "+value+">"); } for(String word : invalidsql){ if(word.equalsIgnoreCase(value) || value.contains(word)){ if(value.contains("<")){ value = value.replace("<", "<"); } if(value.contains(">")){ value = value.replace(">", ">"); } request.getSession().setAttribute("sqlInjectError", "the request parameter \""+value+"\" contains keyword: \""+word+"\""); response.sendRedirect(request.getContextPath()+error); return; } } } fc.doFilter(req, res); } public void init(FilterConfig conf) throws ServletException { String sql = conf.getInitParameter("invalidsql"); String errorpage = conf.getInitParameter("error"); String de = conf.getInitParameter("debug"); if(errorpage != null){ error = errorpage; } if(sql != null){ invalidsql = Arrays.asList(sql.split(" ")); } if(de != null && Boolean.parseBoolean(de)){ debug = true; System.out.println("PreventSQLInject Filter staring..."); System.out.println("print filter details"); System.out.println("invalid words as fllows (split with blank):"); for(String s : invalidsql){ System.out.print(s+" "); } System.out.println(); System.out.println("error page as fllows"); System.out.println(error); System.out.println(); } } }
2.web.xml中添加如下配置:
<filter> <filter-name>PreventSqlInject</filter-name> <filter-class>cn.kepu.filter.SqlInjectFilter</filter-class> <!-- filter word, split with blank --> <init-param> <param-name>invalidsql</param-name> <param-value>select insert delete from update create destory drop alter and or like exec count chr mid master truncate char declare ; - ' % < ></param-value> </init-param> <!-- error page --> <init-param> <param-name>error</param-name> <param-value>/error.jsp</param-value> </init-param> <!-- debug --> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>PreventSqlInject</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
3,在根目录下添加error.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>防sql注入系统</title> </head> <body> 这个是防sql注入系统,自动过滤您的请求,请更换请求字符串。 <%=session.getAttribute("sqlInjectError")%> <p><a href="<%=path%>">点此返回</a></p> </body>