当前位置:   article > 正文

记录一次修复XSS安全漏洞_esapi.encoder().encodeforurl

esapi.encoder().encodeforurl

 

前几天收到安全部门的邮件:你负责的项目有个XSS安全漏洞需要修复。我内心:安全知识倒是了解些,到底该怎么去修复,还是一头雾水。。。

什么是XSS呢?

XSS漏洞为跨站脚本漏洞,分为反射型、持久型、DOM型。反射型漏洞的触发是用户点击了被篡改的URL,篡改的数据经前端传到后端后展示在前端,并在前端执行,受影响的是指定浏览器;持久型漏洞是用户输入非法内容,经前端上传到后端,并入库,后经后端传给前端,在前端执行,受影响的是任何访问指定连接的浏览器;DOM型漏洞是用户点击了被篡改的url,篡改后的数据直接在浏览器执行。

具体XSS案例可以看看其它博客,都有明确讲述,不多BB,来先看下我司的奇安信代码卫视扫描出所负责的代码漏洞:

提示下方28行代码有问题:

下方这个提示 26,27行有问题:

 

再来看看给的修复建议:

  1. 为了避免反射型XSS攻击,建议采用以下方式进行防御:
  2. 1.对用户的输入进行合理验证(如年龄只能是数字),对特殊字符(如`<、>、'、"以及\<script\>、javascript`等进行过滤。
  3. 2.根据数据将要置于HTML上下文中的不同位置(HTML标签、HTML属性、JavaScript脚本、CSS、URL),对所有不可信数据进行恰当的输出编码。
  4. **例如**:采用OWASP ESAPI对数据输出HTML上下文中不同位置,编码方法如下。
  5. ```java
  6. //HTML encode
  7. ESAPI.encoder().encodeForHTML(inputData);
  8. //HTML attribute encode
  9. ESAPI.encoder().encodeForHTMLAttribute(inputData);
  10. //JavaScript encode
  11. ESAPI.encoder().encodeForJavaScript(inputData);
  12. //CSS encode
  13. ESAPI.encoder().encodeForCSS(inputData);
  14. //URL encode
  15. ESAPI.encoder().encodeForURL(inputData);
  16. ```
  17. 3.设置HttpOnly属性,避免攻击者利用跨站脚本漏洞进行Cookie劫持攻击。在Java EE中,给Cookie添加HttpOnly的代码如下:
  18. ```java
  19. ...
  20. response.setHeader("Set-Cookie","cookiename=cookievalue; path=/; Domain=domainvaule; Max-age=seconds; HttpOnly");

这修复建议看了后似乎对于上述没啥大的帮助啊。然后经过看别人博客和思考,用以下方式解决:

对于第一个案例:

  1. String serverName = req.getServerName();
  2. String host = HtmlUtils.htmlEscape(req.getHeader("host"));
  3. obj.addProperty("serverName", serverName);
  4. obj.addProperty("header-host", host);

因为项目使用的是Spring,便用Spring的HtmlUtils.htmlEscape 对request.getHeader("host")进行转译,防止host里面植入html或者sql语句,那如果host篡改呢,这就涉及到CSRF跨站攻击了,下次在写一篇实战解决CSRF跨站攻击案例,目前这段代码只是针对单个方法进行转译,那如果其它方法也有类似,不是要重复写很多?那我们可以用如下方案(因为项目使用springboot方式,直接用bean注入相应filter)

  1. public class XssSpringFilter implements Filter {
  2. @Override
  3. public void init(FilterConfig filterConfig) throws ServletException {
  4. }
  5. @Override
  6. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  7. HttpServletRequest req = (HttpServletRequest) request;
  8. chain.doFilter(new XssSpringHttpServletRequestWrapper(req), response);
  9. }
  10. @Override
  11. public void destroy() {
  12. }
  13. }
  1. public class XssSpringHttpServletRequestWrapper extends HttpServletRequestWrapper {
  2. public XssSpringHttpServletRequestWrapper(HttpServletRequest request) {
  3. super(request);
  4. }
  5. /**
  6. * 对数组参数进行特殊字符过滤
  7. */
  8. @Override
  9. public String[] getParameterValues(String name) {
  10. String[] values = super.getParameterValues(name);
  11. if(values == null){
  12. return null;
  13. }
  14. String[] newValues = new String[values.length];
  15. for (int i = 0; i < values.length; i++) {
  16. //spring的HtmlUtils进行转义
  17. newValues[i] = HtmlUtils.htmlEscape(values[i]);
  18. }
  19. return newValues;
  20. }
  21. /**
  22. * 拦截参数,并对其进行字符转义
  23. */
  24. @Override
  25. public String getParameter(String name) {
  26. String value = super.getParameter(name);
  27. return HtmlUtils.htmlEscape(value);
  28. }
  29. /**
  30. * 拦截header,并对其进行字符转义
  31. */
  32. @Override
  33. public String getHeader(String name) {
  34. String value = super.getHeader(name);
  35. return HtmlUtils.htmlEscape(value);
  36. }
  1. @Configuration
  2. public class FilterConfig extends WebMvcConfigurerAdapter {
  3. @Bean
  4. public FilterRegistrationBean xssSpringFilter() {
  5. FilterRegistrationBean registration = new FilterRegistrationBean();
  6. registration.setFilter(new XssSpringFilter());
  7. registration.addUrlPatterns("/*");
  8. registration.setName("xssSpringFilter");
  9. registration.setOrder(-1);
  10. return registration;
  11. }
  12. }

 

对于第二个案例,因为url是通过我们内部服务获取的域名,获取的内容不会被篡改,所以也就不用改了,也不能全信代码扫描工具呀

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/150598
推荐阅读
相关标签
  

闽ICP备14008679号