Java过滤器如何解决存储型xss攻击问题
作者:冯浩月
Java过滤器解决存储型xss攻击
XSS攻击场景
攻击者可以通过构造URL注入JavaScript、VBScript、ActiveX、HTML或者Flash的手段,利用跨站脚本漏洞欺骗用户,收集Cookie等相关数据并冒充其他用户。
通过精心构造的恶意代码,可以让访问者访问非法网站或下载恶意木马,如果再结合其他攻击手段(如社会工程学、提权等),甚至可以获取系统的管理权限。
举例说明
例如:
在项目看板里待材料初审存储下面代码,点击A项目会弹出框
Payload: <iframe οnlοad=alert("xss");></iframe>
例如:
全部阶段结果标准-存储下面代码,点击20200927测试-2
Payload: <textarea οnfοcus=alert("xss"); autofocus>
解决方案
找到项目已有的filter过滤器,在过滤HttpServletRequest参数时,进行参数的处理,使用转义,将 < 转义为 & lt , > 转义为 & gt
public PaasHttpRequestWrapper(HttpServletRequest request) { super(request); StringBuilder stringBuilder = new StringBuilder(); InputStream inputStream = null; try { inputStream = request.getInputStream(); } catch (IOException e) { throw new RuntimeException(e); } if (inputStream != null) { try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) { char[] charBuffer = new char[CHAR_BUFFER_LENGTH]; int bytesRead; while ((bytesRead = bufferedReader.read(charBuffer)) > 0) { stringBuilder.append(charBuffer, BUFFER_START_POSITION, bytesRead); } } catch (IOException e) { e.printStackTrace(); } } else { stringBuilder.append(""); } body = stringBuilder.toString(); // 解决xss攻击问题 if (body.contains("<")) { body = body.replace("<", "<"); } if (body.contains(">")) { body = body.replace(">", ">"); } initParameterMap(); }
XSS攻击及解决方案
什么是XSS攻击?
XSS攻击使用Javascript脚本注入进行攻击
XSS攻击常出现在提交表单中,如博客的评论区等,用户可以通过提交评论:<script>alert("你的网站太垃圾了!")</script>,那么只要访问该页面的用户都会弹窗,当然,这可能是为了娱乐娱乐,不要小看XSS攻击,有些人利用XSS攻击窃取用户名密码,调用黑客的工程,将用户名和密码发送过去,也可以伪装成钓鱼网站。
例如在表单中注入: <script>location.href='http://www.xxx.com'</script> 那么页面会跳转到xxx.com
还可以根据js获取本地浏览器的cookie信息,根据cookie信息完全可以模拟用户。
注意:谷歌浏览器 已经防止了XSS攻击,为了演示效果,最好使用火狐浏览器。
那么该如何防止XSS攻击呢?
实现思路:
使用转义解决。将<转义为< >转义为>
- ①使用过滤器,拦截所有请求,重写request
- ②重写获取值的方法,将特殊代码转换成html
具体代码实现:
- XssHttpServletRequest.java
package cn.itcats; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import org.apache.commons.lang3.StringEscapeUtils; import org.apache.commons.lang3.StringUtils; public class XssHttpServletRequest extends HttpServletRequestWrapper{ private HttpServletRequest request; //需要重写构造方法 public XssHttpServletRequest(HttpServletRequest request) { super(request); this.request = request; } //需要重写getParameter(name)方法,将value进行转义 public String getParameter(String name) { String value = request.getParameter(name); System.out.println("没有转义之前:value="+value); if(StringUtils.isNotBlank(value)){ //转化为html,<script>标签都会转化为html格式 <script> //工具类来自于org.apache.commons.lang3.StringEscapeUtils value = StringEscapeUtils.escapeHtml4(value); } return value; } }
- web.xml配置过滤器
<!-- 防止XSS攻击 --> <filter> <filter-name>FilterXSS</filter-name> <filter-class>cn.itcats.FilterXSS</filter-class> </filter> <filter-mapping> <filter-name>FilterXSS</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
- FilterXss.java
package cn.itcats; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; public class FilterXSS implements Filter{ public void init(FilterConfig filterConfig) throws ServletException { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //强转为HttpServletRequest HttpServletRequest req = (HttpServletRequest)request; //需要重写request,重建一个类XssHttpServletRequest 继承 HttpServletRequestWrapper,重写构造和getParameter方法 XssHttpServletRequest xssHttpServletRequest = new XssHttpServletRequest(req); //务必传入是重写过的request,放行 chain.doFilter(xssHttpServletRequest, response); } public void destroy() { } }
注意:只要是文本框、表单等,需要提交并在页面展示的,一般都需要做防XSS攻击。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。