防SQL注入
/**
* 待完善
*/
最近在所做的一个项目中优化一个防SQL注入的功能模块,过程中遇到了一些问题,于是上网搜了一些资料,自己也作了一些思考。
在我了解的知识范围里,web项目防SQL注入的实现方式大同小异,一般为对表单项进行字符屏蔽比较常见。
1、你可以使用过滤器(Filter)拦截所有表单:如果对表单输入项没有特殊要求,这种方式实现起来快速、方便、有效,实现起来也比较简单;
2、也可以使用切面技术,对表单分别设置,这种方式可能稍显麻烦,但是可以对不同表单进行个性化设置(有一些表单需要防SQL注入,有一些表单不能加入这样的限制)。
具体怎么屏蔽字符串,我想我不用多说了,网上到处都是,下面是字符屏蔽的核心代码,仅供参考:
1 /** 2 * 需要屏蔽的字符串可以根据需求自行定义 3 */ 4 private String[] STRCOMPARETMP = { "and ", "exec ", "insert ", "select ", 5 "delete ", "update ", "*", "%", "truncate ", "declare ", "or ", 6 "drop ", "alter ", "var ", "<script", "'", "\"", "and ", 7 "exec ", "insert ", "select ", "delete ", "update ", 8 "truncate ", "declare ", "or ", "drop ", "alter ", "var " }; 9 /** 10 * 11 * @param request 12 * @param response 13 * @param chain 14 * @throws IOException ServletException 15 */ 16 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 17 HttpServletRequest req = (HttpServletRequest) request; 18 HttpServletResponse res = (HttpServletResponse) response; 19 Iterator values = req.getParameterMap().values().iterator();// 获取所有的表单参数 20 boolean filter = true; 21 while (values.hasNext() && filter) { 22 String[] value = (String[]) values.next(); 23 for (int i = 0; i < value.length; i++) { 24 for (int j = 0; j < STRCOMPARETMP.length; j++) { 25 if (value[i].toLowerCase().indexOf(" " + STRCOMPARETMP[j] + " ") >= 0) { 26 filter = false; 27 httpResponse .sendRedirect(httpRequest .getContextPath() + "/login.jsp");//含非法字符则重定向会登陆页面 28 return; 29 } 30 } 31 } 32 } 33 if(filter){ 34 chain.doFilter(request, response); 35 } 36 }
这里还需要说明以下几点:
1、你的表单数据进入后台之后通过什么方式与数据库打交道的?如果你使用的是JDBC,并且使用PrepareStatement(代替Statement),那你就中彩了,PrepareStatement类已经防SQL注入了。并且使用此类还有两个好处:提升代码的可读性和可维护性、提高SQL执行的效率。所以作者比较建议大家使用PrepareStatement类。
2、如果需要对表单数据进行防SQL注入限制,记得你不仅要做小写字符的限制还需要做大写字符限制,限制的字符请根据实际需求仔细斟酌,不要为后续的其他功能带来负面影响。比如说你字符屏蔽中有“or ”字符,那么你的表单数据甚至不能包含“actor ”、“employor ”这样的字符串了,这可能会影响其他功能;再比如说你要对“ or ”字符进行限制,那你一定要记得需要限制的字符还可能包含“ or ”、“ or ”、“ or ”……
3、……