记录一次修复XSS安全漏洞

 

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

什么是XSS呢?

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

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

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

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

 

再来看看给的修复建议:

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

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

对于第一个案例:

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

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

public class XssSpringFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,     FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        chain.doFilter(new XssSpringHttpServletRequestWrapper(req), response);
    }

    @Override
    public void destroy() {

    }
}
public class XssSpringHttpServletRequestWrapper extends HttpServletRequestWrapper {

    public XssSpringHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
    }
    /**
     * 对数组参数进行特殊字符过滤
     */
    @Override
    public String[] getParameterValues(String name) {
        String[] values = super.getParameterValues(name);
        if(values == null){
            return null;
        }
        String[] newValues = new String[values.length];
        for (int i = 0; i < values.length; i++) {
            //spring的HtmlUtils进行转义
            newValues[i] = HtmlUtils.htmlEscape(values[i]);
        }
        return newValues;
    }

    /**
     * 拦截参数,并对其进行字符转义
     */
    @Override
    public String getParameter(String name) {
        String value = super.getParameter(name);
        return HtmlUtils.htmlEscape(value);
    }
     /**
     * 拦截header,并对其进行字符转义
     */
    @Override
    public String getHeader(String name) {
        String value = super.getHeader(name);
        return HtmlUtils.htmlEscape(value);
    }
@Configuration
public class FilterConfig extends WebMvcConfigurerAdapter {
    @Bean
    public FilterRegistrationBean xssSpringFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new XssSpringFilter());
        registration.addUrlPatterns("/*");
        registration.setName("xssSpringFilter");
        registration.setOrder(-1);
        return registration;
    }
}

 

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

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值