XSS跨站指令碼攻擊以及解決辦法
來源:https://www.cnblogs.com/insaneXs/p/7465014.html
XSS,全稱為Cross Site Script,跨站指令碼攻擊,是WEB程式中一種常見的漏洞。其主要的攻擊手段是在在利用網站上的可由使用者輸入資訊的地方,惡意注入含有攻擊性的指令碼,達到攻擊網站或者竊取使用者cookied等隱私資訊的目的。
XSS漏洞主要分為兩種型別,一種是Stored XSS, 另一種是反射型 XSS。
第一種舉個簡單的例子就是BBS網站,黑客可以利用留言的功能,發表以下內容:
<script type="text/javascript"> alert("surprise") </script>
對系統而言,它認為這和其他的留言一樣都只是字串。但是當有使用者訪問到這個頁面時,瀏覽器會把這段留言當成html內容來解析。因此就執行了其中的js指令碼。
而反射型 XSS則是利用點選連結或是提交一些內容來達到攻擊的目的。
比如我有以下一個頁面:
<form name="formsearch" method="get"> <div class="form"> <input name="q" type="text" class="search-keyword" id="search-keyword" /> <button type="submit" class="search-submit blue-button">搜尋</button> </div> </form>
當用戶在input框中輸入: "<script type="text/javascript"> alert(“surperise”) " 時。他也向瀏覽器插入了自己的JS指令碼。
當表單被提交時,輸入的字串被作為引數放在了URL中,傳到下一個頁面。
當下一個頁面需要顯示這些內容,字串中包含的攻擊指令碼也就被瀏覽器解釋了出來。
當然這段指令碼只能在自己的瀏覽器執行,可能沒有什麼攻擊性,但是黑客們會想盡辦法偽裝頁面達到攻擊的目的。
總之,XSS攻擊就是想辦法讓你的瀏覽器去執行他的指令碼。
那麼XSS攻擊該如何預防呢?
既然是通過輸入字串達到植入指令碼的目的,那麼我們只要對使用者輸入的字串進行一個html轉義處理就好了。
我們可以利用org.apache.commons.lang3.StringEscapeUtils(注:3.6版本起,用commons-text包下的StringEscapeUtils代替)這個類對輸入的引數進行html轉義。
可以定義一個過濾器,然後轉義HttpServletRequest中的引數值。
程式碼如下:
定義攔截器
1 import java.io.IOException;
2
3 import javax.servlet.Filter;
4 import javax.servlet.FilterChain;
5 import javax.servlet.FilterConfig;
6 import javax.servlet.ServletException;
7 import javax.servlet.ServletRequest;
8 import javax.servlet.ServletResponse;
9 import javax.servlet.http.HttpServletRequest;
10
11 public class XSSFilter implements Filter {
12 @Override
13 public void init(FilterConfig filterConfig) throws ServletException {
14
15 }
16
17 @Override
18 public void doFilter(ServletRequest request, ServletResponse response,
19 FilterChain chain) throws IOException, ServletException {
20 chain.doFilter(new XSSHttpServletRequestWrapper((HttpServletRequest) request), response);
21 }
22
23 @Override
24 public void destroy() {
25
26 }
27
28
29 }
由於原生的HttpServletRequest不支援你直接修改引數,因此我們定義了一個包裝類,在獲取引數的時候對引數進行轉義。
1 package com.jspxcms.core.support;
2
3 import javax.servlet.http.HttpServletRequest;
4 import javax.servlet.http.HttpServletRequestWrapper;
5
6 import org.apache.commons.lang3.StringEscapeUtils;
7
8 public class XSSHttpServletRequestWrapper extends HttpServletRequestWrapper {
9
10 public XSSHttpServletRequestWrapper(HttpServletRequest request) {
11 super(request);
12 }
13
14 @Override
15 public String getHeader(String name) {
16 return StringEscapeUtils.escapeHtml4(super.getHeader(name));
17 }
18
19 @Override
20 public String getQueryString() {
21 return StringEscapeUtils.escapeHtml4(super.getQueryString());
22 }
23
24 @Override
25 public String getParameter(String name) {
26 return StringEscapeUtils.escapeHtml4(super.getParameter(name));
27 }
28
29 @Override
30 public String[] getParameterValues(String name) {
31 String[] values = super.getParameterValues(name);
32 if(values != null) {
33 int length = values.length;
34 String[] escapseValues = new String[length];
35 for(int i = 0; i < length; i++){
36 escapseValues[i] = "1";
37 }
38 return escapseValues;
39 }
40 return super.getParameterValues(name);
41 }
42 }
最後我們在web.xml中配置我們的攔截器即可(將XXXX換成類的全限定名)。
1 <filter>
2 <filter-name>XssEscape</filter-name>
3 <filter-class>XXXXX.XSSFilter</filter-class>
4 </filter>
5 <filter-mapping>
6 <filter-name>XssEscape</filter-name>
7 <url-pattern>/*</url-pattern>
8 <dispatcher>REQUEST</dispatcher>
9 </filter-mapping>
簡單的XSS防禦就完成了。