如何尽可能规避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 + "'");

	}
}
相关文章
相关标签/搜索