SQL注入和SCRIPT注入,是一個煩人的東西,那么這個問題該怎么解決呢?下面就說一說如何解決這個問題。
              在項目一開始,如果就考慮到這個問題的話,那是可以完全避免的。
              反script注入:在jsp頁面中解決,增刪查修審都用struts標簽 ,是沒有任何問題的。如果是html標簽的話,用jstl標簽也可以完全解決。
              那么如果用到文本編輯器的時候,又該怎么解決啊?我的反SCRIPT注入就可以解決這個問題了。
              反sql注入:如果是jdbc的話,不要用Statement,用PreparedStatement就可以避免。如果用hibernate的話,用 Criteria查詢就可以解決這個問題。

              如何是在項目快完結的時候才發現這個問題,那該怎么解決啊?
              apache提供了工具類:org.apache.commons.lang.StringEscapeUtils,它里面有對應的方法解決這個問題。
              下面是我自己提供一種方法。

              為了實現反SQL注入和反SCRIPT注入,本例應用反射技術和責任鏈模式實現了這個功能。它對于系統來說是可插撥的,這樣就實現了與系統的松散耦合。
              它的主要思想是:把Form對象,PO對象以及VO等對象中的String型屬性的值或者String類型的參數進行過濾后重新封裝為原有類型的對象。在獲取對象的時候應用了 java反映技術,
          在進行過濾的時候,實現了鏈式過濾。這樣做,就是為了達到可維護性,可擴展性,可重用性以及靈活性的目的。
              以下是源代碼:


          package net.better_best.www.utils.filter;
          public class Request {
              // 存儲需要過濾的字符串
              private String requestStr;
              public String getRequestStr() {
                  return requestStr;
              }
              public void setRequestStr(String requestStr) {
                  this.requestStr = requestStr;
              }
          }


          package net.better_best.www.utils.filter;

          public class FilterConstant {
           //定義sql過濾的內容
           public static String[][] SQL_FILTER = {
            {";",""},
            {"'","''"},
            {"--",""},
            {"%",""}
            };
            //定義script過濾的內容
           public static String[][] SCRIPT_FILTER = {
            {"(<[i|I][n|N][p|P][u|U][t|T])([^>]*)(/>)",""},
            {"(<[i|I][n|N][p|P][u|U][t|T])([\\s\\S]*)(</[i|I][n|N][p|P][u|U][t|T]>)",""},
            {"(<[t|T][a|A][b|B][l|L][e|E])([^>]*)(/>)",""},
            {"(<[t|T][a|A][b|B][l|L][e|E])([\\s\\S]*)(</[t|T][a|A][b|B][l|L][e|E]>)",""},
            {"(<[d|D][i|I][v|V])([^>]*)(/>)",""},
            {"(<[d|D][i|I][v|V])([\\s\\S]*)(</[d|D][i|I][v|V]>)",""},
            {"(<[b|B][u|U][t|T][t|T][o|O][n|N])([^>]*)(/>)",""},
            {"(<[b|B][u|U][t|T][t|T][o|O][n|N])([\\s\\S]*)(</[b|B][u|U][t|T][t|T][o|O][n|N]>)",""},
            {"(<[s|S][c|C][r|R][i|I][p|P][t|T])([^>]*)(/>)",""},
            {"(<[s|S][c|C][r|R][i|I][p|P][t|T])([\\s\\S]*)(</[s|S][c|C][r|R][i|I][p|P][t|T])(>)",""},
            };
          }



          package net.better_best.www.utils.filter;

          public interface IFilter {
              void doFilter(Request request, FilterChain chain);
          }



           

          package net.better_best.www.utils.filter;

          public class SqlFilter implements IFilter {
              @Override
              //進行sql過濾
              public void doFilter(Request request, FilterChain chain) {
                  if (request != null) {
                   String strRequest = request.getRequestStr();
                   String[][] sqlFilter = FilterConstant.SQL_FILTER;
                   for (String[] strings : sqlFilter) {
                    strRequest = strRequest.replace(strings[0], strings[1]);
             }
                   request.setRequestStr(strRequest);
                  }
                  chain.doFilter(request, chain);
               
              }
          }




          package net.better_best.www.utils.filter;

          public class ScriptFilter implements IFilter {
           @Override
           //進行script過濾
           public void doFilter(Request request, FilterChain chain) {
            if (request != null) {
             String strRequest = request.getRequestStr();
             String[][] scriptFilter = FilterConstant.SCRIPT_FILTER;
                   for (String[] strings : scriptFilter) {
                    strRequest = strRequest.replaceAll(strings[0], strings[1]);
             }
             request.setRequestStr(strRequest);
            }
            chain.doFilter(request, chain);

           }
          }




          package net.better_best.www.utils.filter;

          public enum FilterType {
           SQL_TYPE,SCRIPT_TYPE ;
          }


          package net.better_best.www.utils.filter;


          public class FilterHelper {
           /*
            * 生成過濾鏈條 參數:String type:過濾類型 返回:FilterChain; 根據過濾類型產生過濾鏈條
            */
           public static FilterChain createFilterChain(FilterType type,FilterChain fChain) throws Exception {
            if (type == null)
             return null;
            else if (type.equals(FilterType.SQL_TYPE))
             return fChain.addFilter(new SqlFilter());
            else if (type.equals(FilterType.SCRIPT_TYPE))
             return fChain.addFilter(new ScriptFilter());
            else
             return null;
           }

           /*
            * 把要過濾的字符串封裝成Request對象
            */
           public static Request init(String str) throws Exception {
            if (str == null || str == "")
             return null;
            Request request = new Request();
            request.setRequestStr(str);
            return request;
           }

           /*
            * 對Request對象進行循環過濾
            */
           public static String result(Request request, FilterChain fChain)
             throws Exception {
            if (request == null || fChain == null || fChain.size() == 0)
             return null;
            fChain.doFilter(request, fChain);
            return request.getRequestStr();
           }
          }


          package net.better_best.www.utils.filter;
          import java.util.ArrayList;
          import java.util.List;

          public class FilterChain implements IFilter {
              // 使用 List 保存過濾器
              private List<IFilter> filters = new ArrayList<IFilter>();
              private int index = 0;
              // 用于添加過濾器,可以添加實現了IFilter接口的FilterChain
              public FilterChain addFilter(IFilter f) {
                  this.filters.add(f);
                  return this;
              }
              @Override
              public void doFilter(Request request,  FilterChain chain) {
                  // 判斷是否是否遍歷到 List 的最大值,如果是 return
                  if (index == filters.size())
                      return;
                  // 逐一獲取過濾器
                  IFilter f = filters.get(index);
                  // 此過濾器鏈的下標,是遍歷過濾器的索引
                  index++;
                  // 使用列表中的第index個過濾器,將更改后的 request ,chain 傳進去,
                  f.doFilter(request,chain);
                  index = 0;
              }
              public int size(){
               return filters.size();
              }
          }


          package net.better_best.www.utils;

          import java.lang.reflect.Field;

          import net.better_best.www.utils.filter.FilterChain;
          import net.better_best.www.utils.filter.FilterHelper;
          import net.better_best.www.utils.filter.FilterType;

          public class Filter {
           /*
            * 參數:Object,接收ActionForm,Plain Object,View.Object的屬性值應為單值類型,不能為復合類型或數組類型;
            * 參數:FilterType,定義需要過濾的類型; 返回值:Object; 作用:根據已定義的過濾規則,過濾所傳入Object值;
            */
           public static Object objectFilter(Object obj, FilterType... types) {
            if (obj == null)return obj;
            Class clazz = obj.getClass();
            if (clazz.isArray() || clazz.isInterface() || clazz.isPrimitive())return obj;
            Field[] fds = clazz.getDeclaredFields();
            for (Field field : fds) {
             if (field.getType().getName().equals("java.lang.String")) {
              field.setAccessible(true);
              Object before = null;
              try {
               before = field.get(obj);
              } catch (IllegalArgumentException e) {
               e.printStackTrace();
              } catch (IllegalAccessException e) {
               e.printStackTrace();
              }
              if (before != null)
               try {
                field.set(obj, doFilter(before.toString(), types));
               } catch (IllegalArgumentException e) {
                e.printStackTrace();
               } catch (IllegalAccessException e) {
                e.printStackTrace();
               }
             }
            }
            return obj;
           }

           /*
            * 按照定義好的過濾規則,進行過濾; 參數:String str ,待過濾字符串 返回:String; 已過濾字符串
            */
           public static String doFilter(String str, FilterType... types) {
            if (str == null || str == "")
             return null;
            FilterChain fChain = new FilterChain();
            String result = "";
            try {
             if (types.length == 0) {
              FilterType[] filterTypes = FilterType.values();
              for (FilterType filterType : filterTypes) {
               fChain = FilterHelper.createFilterChain(filterType, fChain);
              }
             } else {
              for (FilterType type : types) {
               fChain = FilterHelper.createFilterChain(type, fChain);
              }
             }
             if (fChain == null) {
              result = str;
             } else {
              result = FilterHelper.result(FilterHelper.init(str), fChain);
             }

            } catch (Exception e) {
             e.printStackTrace();
            }
            return result;
           }
          }



               使用方法:調用Filter的兩個方法,就可以了。

              以上內容為全部代碼;


                歡迎對本文的內容提出不同見解和質疑,不勝感激。
                如果疑問,可發郵件聯系我。可發郵件索取源代碼。
                



             

          Feedback

          # re: 反SQL注入和SCRIPT注入-------------責任鏈模式的應用  回復  更多評論   

          2010-01-13 16:43 by 超級笨笨
          可以,對我有幫助

          # re: 反SQL注入和SCRIPT注入-------------責任鏈模式的應用  回復  更多評論   

          2010-01-14 15:41 by Lancelot
          為什么要做這些無用功???

          正解應該是表單提交時,允許用戶提交各種數據,通過“SET PARAMETER”方式傳入sql中(不管是自己,還是通過ORM都可以很容易實現),這樣來解決sql注入。

          至于script注入,只需要再在上面的基礎上,根據需要顯示出相應的格式就可以了,比如:“jstl”的“out” 可以設置 “escapeXml”、“struts”的“write”可以設置“flter”。

          # re: 反SQL注入和SCRIPT注入-------------責任鏈模式的應用  回復  更多評論   

          2010-01-15 11:19 by java小爬蟲
          @Lancelot
          你好,你說的東西,我都試過了,都是可以的。

          但是有一個問題:

          就是AJAX方式,查詢結果是用字符串拼接起來的,這種情況怎么解決啊?我目前還沒有找到結果辦法。謝謝...

          # re: 反SQL注入和SCRIPT注入-------------責任鏈模式的應用  回復  更多評論   

          2010-01-15 11:20 by java小爬蟲
          @超級笨笨
          歡迎對以上代碼挑刺...

          呵呵呵

          # re: 反SQL注入和SCRIPT注入-------------責任鏈模式的應用  回復  更多評論   

          2010-01-15 11:53 by Lancelot
          以struts為例,只要調用org.apache.struts.util.ResponseUtils.filter(String value),方法就是了,有什么問題???

          # re: 反SQL注入和SCRIPT注入-------------責任鏈模式的應用  回復  更多評論   

          2010-01-15 13:00 by java小爬蟲
          @Lancelot

          舉個例子:

          public ActionForward getNewsList(
          ActionMapping mapping, ActionForm form, HttpServletRequest request,
          HttpServletResponse response) {

          try {
          PrintWriter out = init(request, response);
          PageInfo pageinfo = newsService.getNewsPerPage(
          ParameterCode.curpage_first, ParameterCode.pageSize_10, "");
          List<NewsTable> newsList = pageinfo.getPagedata();
          if (newsList != null && newsList.size() > 0) {
          out.print("<UL>");
          for (NewsTable news : newsList) {

          out.print("<li>.<a href='aa.html' title='"
          + news.getNewsTitle() + "' >"
          + news.getNewsTitle() + "</a></li>");

          }
          out.print("</UL>");
          out.close();
          }
          }
          catch (Exception e) {

          e.printStackTrace();
          }
          return null;
          }


          ajax會調用這個方法,那么org.apache.struts.util.ResponseUtils.filter(news.getNewsTitle())就這樣過濾嗎?

          # re: 反SQL注入和SCRIPT注入-------------責任鏈模式的應用  回復  更多評論   

          2010-01-15 13:57 by Lancelot
          雖然不贊成你這種寫法,不過在你這中應用場景里就是這么用,這總比你費盡周折的造出那么個東西來的要好。

          # re: 反SQL注入和SCRIPT注入-------------責任鏈模式的應用  回復  更多評論   

          2010-01-15 18:05 by java小爬蟲
          @Lancelot
          其實,在項目開始的時候,就考慮script和sql注入,是可以完全避免這個問題的。


          但是如果到了項目后期的話,我這個東西還是可是用的,自我感覺良好,還可以用于系統定義的非法字符的過濾,呵呵呵,


          不過,你的建議讓我學到了不少東西,謝謝你...

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 无极县| 右玉县| 松滋市| 勐海县| 开封市| 包头市| 分宜县| 军事| 兴仁县| 永春县| 黎平县| 侯马市| 岳西县| 德阳市| 隆德县| 商南县| 宁夏| 三穗县| 昭觉县| 石泉县| 临沧市| 澄江县| 玉溪市| 蓬莱市| 义马市| 浙江省| 佛教| 南宁市| 政和县| 瓦房店市| 故城县| 红桥区| 民县| 林西县| 从江县| 都兰县| 瑞昌市| 长宁县| 凤庆县| 迁安市| 南宫市|