如何儘可能規避XSS(跨站點腳本)攻擊

        跨站攻擊,即Cross Site Script Execution(一般簡寫爲XSS,由於CSS與層疊樣式表同名,故改成XSS) 是指攻擊者利用網站程序對用戶輸入過濾不足,輸入能夠顯示在頁面上對其餘用戶形成影響的HTML代碼,從而盜取用戶資料、利用用戶身份進行某種動做或者對訪問者進行病毒侵害的一種攻擊方式。 這種漏洞(XSS)一般用於發動cookie竊取、惡意軟件傳播(蠕蟲攻擊),會話劫持,惡意重定向。javascript

     
        像在上方這種類型的網站,若是提交搜索的內容爲爲: </div><script type="text/javascript">alert('跨站攻擊啦')</script><div>html

        那麼在點擊搜索後,頁面會彈出alert提示信息:跨站攻擊啦java

         對其餘用戶有什麼威脅呢?僅針對此狀況來講,正常狀況下,A用戶提交內容後,服務器都會將內容保存到數據庫服務器中,那麼B用戶若是訪問到了A用戶評論的那個界面就會彈出上面的對話框。這就影響了網站總體體驗。react

       解決辦法:  後臺給div賦值時候,請用html encode編碼將上面btn按鈕的事件,您搜索的內容是:HttpUtility.HtmlEncode(txtSearch.Text.Trim()) 就好了。 以下圖,就不會彈出對話框來了,而是將搜索內容徹底展現出來。數據庫

        咱們來查看html源碼,看見 html標籤信息都被編碼了,這樣瀏覽器就不知道這是一個腳本代碼express

<div id="MainContent_result">您搜索的內容是: &lt;/div&gt;&lt;script type=&quot;text/javascript&quot;&gt;alert(&#39;跨站攻擊鳥&#39;)&lt;/script&gt;&lt;div&gt;</div>apache

        上面 面演示的是一個很是簡單的XSS攻擊,還有不少隱蔽的方式,可是其核心都是利用了腳本注入。所以咱們解決辦法其實很簡單:不信賴用戶輸入,對特殊字符如」<」,」>」轉義,就能夠從根本上防止這一問題。固然不少解決方案都對XSS作了特定限制,但防不勝防,總有些聰明的惡意用戶會到咱們的網站搞破壞,對本身站點不放心能夠看看這個XSS跨站測試代碼大全試試站點是否安全。瀏覽器

        XSS攻擊能夠進行session劫持:Hack經過腳本注入到應用服務器,待其餘真實用戶A登陸訪問含有XSS腳本的網頁,腳本激活,將客戶的session信息發送給Hack,Hack就使用該session直接扮演用戶A訪問服務器。這種session劫持主要靠XSS漏洞和客戶端獲取sessionId完成,防範分兩步:安全

        一、過濾用戶輸入,防止XSS漏洞服務器

        2.、設置sessionId的cookie爲HttpOnly,使客戶端沒法獲取

參考:

http://www.cnblogs.com/StudyLife/p/3514038.html

http://www.cnblogs.com/dolphinX/p/3391351.html

http://www.cnblogs.com/dolphinX/p/3403027.html

http://www.cnblogs.com/dsky/archive/2012/04/06/2434768.html

http://netsecurity.51cto.com/art/201310/414089_1.htm

下面給出struts2中對url進行攔截判斷是否存在xss腳本攻擊的案例:

重寫struts2的攔截器爲SCVStrutsFilter

import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;

import javax.servlet.FilterChain;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter;
import org.apache.struts2.util.URLDecoderUtil;

public class SCVStrutsFilter extends StrutsPrepareAndExecuteFilter {

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
			ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		String target = req.getRequestURI();
		if (checkXss(target)) {
			((HttpServletResponse) response).sendRedirect(req.getContextPath() + "/jsp/common/security.jsp");
			return;
		}
		super.doFilter(request, response, chain);
	}

	/**
	 * 校驗是否含XSS腳本
	 * 
	 * @param value
	 * @return
	 */
	private boolean checkXss(String value) {
		boolean flag = false;
		if (StringUtils.isNotBlank(value)) {
			try {
				// URL解碼
				String decodeFirst = URLDecoder.decode(value, "UTF-8");
				String decodeSec = URLDecoder.decode(decodeFirst, "UTF-8");
				// 檢查第一次解碼是否存在XSS
				flag = XssShieldUtil.matcherXss(decodeFirst);
				// 若是第一次解碼已經存在XSS或兩次解碼同樣則不進行第二次解碼檢驗
				if (!flag && !StringUtils.equals(decodeFirst, decodeSec)) {
					flag = XssShieldUtil.matcherXss(decodeSec);
				}
			} catch (Exception e) {
				log.error("請求URL解碼出錯", e);
			}
		}
		return flag;
	}

}

對應XSS腳本檢測工具類XssShieldUtil以下

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;

/**
 * XSS腳本過濾工具
 */
public class XssShieldUtil {

	/**
	 * 默認的XSS攻擊腳本匹配規則
	 */
	private static List<Pattern> patterns = null;

	static {
		patterns = new ArrayList<Pattern>();
		// 匹配<script>***</script>
		patterns.add(Pattern.compile("<(no)?script[^>]*>.*?</(no)?script>", Pattern.CASE_INSENSITIVE));
		// 匹配eval(***)
		patterns.add(Pattern.compile("eval\\s*\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE
				| Pattern.DOTALL));
		// 匹配expression(***)
		patterns.add(Pattern.compile("expression\\s*\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE
				| Pattern.DOTALL));
		// 匹配javascript:或vbscript:或view-source:
		patterns.add(Pattern.compile("(javascript\\s*:|vbscript\\s*:|view-source\\s*:)+", Pattern.CASE_INSENSITIVE));
		// 匹配<>或<**'##'**"##"**>
		patterns.add(Pattern.compile("<(\"[^\"]*\"|\'[^\']*\'|[^\'\">])*?>", Pattern.CASE_INSENSITIVE
				| Pattern.MULTILINE | Pattern.DOTALL));
		// 匹配window.location或window.或.location或document.cookie或document.或alert(***)或或window.open
		patterns
				.add(Pattern
						.compile(
								"(window\\.location|window\\.|\\.location|document\\.cookie|document\\.|alert\\s*\\(.*?\\)|window\\.open)+",
								Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL));
		// 匹配「<」開頭裏面含有window事件且「>」結尾
		patterns
				.add(Pattern
						.compile(
								"<+\\s*\\w*\\s*(oncontrolselect|oncopy|oncut|ondataavailable|ondatasetchanged|ondatasetcomplete|ondblclick|ondeactivate|ondrag|ondragend|ondragenter|ondragleave|ondragover|ondragstart|ondrop|onerror=|onerroupdate|onfilterchange|onfinish|onfocus|onfocusin|onfocusout|onhelp|onkeydown|onkeypress|onkeyup|onlayoutcomplete|onload|onlosecapture|onmousedown|onmouseenter|onmouseleave|onmousemove|onmousout|onmouseover|onmouseup|onmousewheel|onmove|onmoveend|onmovestart|onabort|onactivate|onafterprint|onafterupdate|onbefore|onbeforeactivate|onbeforecopy|onbeforecut|onbeforedeactivate|onbeforeeditocus|onbeforepaste|onbeforeprint|onbeforeunload|onbeforeupdate|onblur|onbounce|oncellchange|onchange|onclick|oncontextmenu|onpaste|onpropertychange|onreadystatechange|onreset|onresize|onresizend|onresizestart|onrowenter|onrowexit|onrowsdelete|onrowsinserted|onscroll|onselect|onselectionchange|onselectstart|onstart|onstop|onsubmit|onunload)+\\s*=+",
								Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL));
	}

	/**
	 * XSS腳本匹配
	 * 
	 * @param value
	 * @return
	 */
	public static boolean matcherXss(String value) {
		boolean flag = false;
		if (StringUtils.isNotBlank(value)) {
			Matcher matcher = null;
			for (Pattern pattern : patterns) {
				matcher = pattern.matcher(value);
				if (matcher.find()) {
					flag = true;
					log.error("攔截URL存在XSS攻擊:" + value);
					break;
				}
			}
		}
		return flag;
	}

	/**
	 * XSS腳本清除
	 * 
	 * @param value
	 * @return
	 */
	public static String stripXss(String value) {
		if (StringUtils.isNotBlank(value)) {
			Matcher matcher = null;
			for (Pattern pattern : patterns) {
				matcher = pattern.matcher(value);
				// 匹配
				if (matcher.find()) {
					System.out.println(value);
					System.out.println(matcher.pattern());
					// 刪除相關字符串
					value = matcher.replaceAll("");
				}
			}
			value = value.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
		}
		return value;
	}

	public static void main(String[] args) {
		// Pattern p = Pattern.compile("<(no)?script[^>]*>.*?</(no)?script>", Pattern.CASE_INSENSITIVE);
		// Matcher matcher = p.matcher("<script language=text/javascript>alert(document.cookie);</script>");
		// System.out.println(matcher.find());

		// System.out.println(StringEscapeUtils.escapeHtml("<sdsjavascript img=\"http://sds/sds.jsp\">"));

		String value = null;
		value = XssShieldUtil.stripXss("<script language=text/javascript>alert(document.cookie);</script>");
		System.out.println("type-1: '" + value + "'");

		value = XssShieldUtil.stripXss("<script src='' onerror='alert(document.cookie)'></script>");
		System.out.println("type-2: '" + value + "'");

		value = XssShieldUtil.stripXss("</script>");
		System.out.println("type-3: '" + value + "'");

		value = XssShieldUtil.stripXss(" eval  	(abc);");
		System.out.println("type-4: '" + value + "'");

		value = XssShieldUtil.stripXss(" expression(abc);");
		System.out.println("type-5: '" + value + "'");

		value = XssShieldUtil.stripXss("<img src='' onerror='alert(document.cookie);'></img>");
		System.out.println("type-6: '" + value + "'");

		value = XssShieldUtil.stripXss("<img src='' onerror='alert(document.cookie);'/>");
		System.out.println("type-7: '" + value + "'");

		value = XssShieldUtil.stripXss("<img src='' onerror='alert(document.cookie);'>");
		System.out.println("type-8: '" + value + "'");

		value = XssShieldUtil.stripXss("<script language=text/javascript>alert(document.cookie);");
		System.out.println("type-9: '" + value + "'");

		value = XssShieldUtil.stripXss("<script>window.location='url'");
		System.out.println("type-10: '" + value + "'");

		value = XssShieldUtil.stripXss(" onload='alert(\"abc\");");
		System.out.println("type-11: '" + value + "'");

		value = XssShieldUtil.stripXss("<img src=x'<!--<\"-->>");
		System.out.println("type-12: '" + value + "'");

		value = XssShieldUtil.stripXss("<=img onstop=");
		System.out.println("type-13: '" + value + "'");

	}
}
相關文章
相關標籤/搜索