XSS攻擊及預防


跨站腳本攻擊(Cross Site Scripting),為不和層疊樣式表(Cascading Style Sheets, CSS)的縮寫混淆,故將跨站腳本攻擊縮寫為XSS。惡意攻擊者往Web頁面里插入惡意Script(php,js等)代碼,當用戶瀏覽該頁之時,嵌入其中Web里面的Script代碼會被執行,從而達到惡意攻擊用戶的特殊目的。

攻擊實例

下面為一個Input標簽:

<input type="text" value="value"></input>

當用輸入值為" onfocus="alert(document.cookie)  時,input標簽內容變為 <input type="text" value=""onfocus="alert(document.cookie)"></input>

當input中的可以執行的js腳本被存儲到數據庫中。用戶再次取出顯示時。就會取到用戶的cookie。從而得到用戶名和密碼。

 (1)添加用戶

 

 (2)數據庫中存儲可執行腳本

 

 (3)編輯用戶(XSS攻擊發生)

 

攻擊危害

  以上獲取用戶名和密碼只是個簡單的xss攻擊,還有跟多的XSS攻擊實例。例如將用戶導航到其他網站,后台掛馬操作等

攻擊預防

 原理主要采用過濾器對請求中的特殊字符進行編碼轉化。從而將可以執行的script代碼變為不可以執行的script腳本存儲到數據庫中。

  示例:開發環境采用的SSH框架。所以采用過濾器,注意這里采用裝飾者模式對請求request對象進行了包裝。

             注:由於使用了struts2.所以要自定義的裝飾者對象繼承StrutsRequestWrapper類。但是這樣對於上傳文件獲得不到參數。因為上傳文件請求類型為MultiPart

             所以包裝對象為原始的請求HttpServletRequestWrapper

            具體代碼:

 

 1 public class XssFilter implements Filter {
 2     
 3     public void destroy() {
 4         
 5     }
 6     
 7     public void doFilter(ServletRequest servletRequest,  ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
 8            XssStrutsRequestWrapper xssRequest = new XssStrutsRequestWrapper((HttpServletRequest) servletRequest);
 9            HttpServletResponse response = (HttpServletResponse)servletResponse;
10            filterChain.doFilter(xssRequest, response);  
11     }
12     
13     public void init(FilterConfig arg0) throws ServletException {
14         
15     }
16     
17 }

 

 

 

        

  1 public class XssStrutsRequestWrapper extends HttpServletRequestWrapper{
  2     private HttpServletRequest orgRequest;
  3     
  4     public XssStrutsRequestWrapper(HttpServletRequest request) {
  5         super(request);
  6         this.orgRequest = request;
  7     }
  8     /** 
  9     * 獲取最原始的request 
 10     * @return 
 11     */  
 12     public HttpServletRequest getOrgRequest() {  
 13         return orgRequest;  
 14     }  
 15     /** 
 16     * 獲取最原始的request的靜態方法 
 17     * @return 
 18     */  
 19     public static HttpServletRequest getOrgRequest(HttpServletRequest req) {  
 20         if (req instanceof XssStrutsRequestWrapper) {  
 21             return ((XssStrutsRequestWrapper) req).getOrgRequest();  
 22         }  
 23         return req;  
 24     }  
 25     /** 
 26      * 覆蓋getParameter方法,將參數名和參數值都做xss過濾。<br/> 
 27      * 如果需要獲得原始的值,則通過super.getParameterValues(name)來獲取<br/> 
 28      * getParameterNames,getParameterValues和getParameterMap也可能需要覆蓋 
 29      */  
 30      @Override  
 31      public String getParameter(String name) {  
 32          String value = super.getParameter(xssEncode(name));  
 33          if (value != null) {  
 34              value = xssEncode(value);  
 35          }  
 36          return value;  
 37      }  
 38    
 39      /** 
 40      * 覆蓋getHeader方法,將參數名和參數值都做xss過濾。<br/> 
 41      * 如果需要獲得原始的值,則通過super.getHeaders(name)來獲取<br/> 
 42      * getHeaderNames 也可能需要覆蓋 
 43      */  
 44      @Override  
 45      public String getHeader(String name) {  
 46          String value = super.getHeader(xssEncode(name));  
 47          if (value != null) {  
 48              value = xssEncode(value);  
 49          }  
 50          return value;  
 51      }  
 52     /**
 53      * 覆蓋getParamterMap方法,
 54      */
 55     @Override
 56     @SuppressWarnings("unchecked")
 57     public Map<String, String[]> getParameterMap() {
 58         Map<String, String[]> paramMap = super.getParameterMap();
 59             Set<String> keySet = paramMap.keySet();
 60             for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
 61                 String key = (String) iterator.next();
 62                 String[] str = paramMap.get(key);
 63                 for(int i=0; i<str.length; i++) {
 64                    // 對參數值進行編碼過濾
 65                    str[i] = xssEncode(str[i]);
 66                 }
 67             }
 68             return paramMap ;
 69      }
 70      public String xssEncode(String source){
 71          if (source == null) {
 72              return "";
 73          }
 74          String html = "";
 75          StringBuffer buffer = new StringBuffer();
 76          for (int i = 0; i < source.length(); i++) {
 77              char c = source.charAt(i);
 78              switch (c) {
 79                  case '<':
 80                      //buffer.append("&lt;");
 81                      buffer.append("<");
 82                      break;
 83                  case '>':
 84                      //buffer.append("&gt;");
 85                      buffer.append(">");
 86                      break;
 87                  case '&':
 88                      //buffer.append("&amp;");
 89                      buffer.append("&");
 90                      break;
 91                  case '"':
 92                      //buffer.append("&quot;");
 93                      buffer.append(""");
 94                      break;
 95                  default:
 96                      buffer.append(c);
 97                  }
 98          }
 99          html = buffer.toString();
100          return html;
101      }
102     
103 }

 

這里編碼實現主要是xssEncode(String source)方法。XssStrutsRequestWrapper必須重寫getParameterMap()方法。並調用xssEncode(String source)編碼。

結果:

數據中內容將英文的“變為全角" 。從而將可以執行的js腳本並未不可執行的腳本存儲在數據庫中。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM