如何在没有SpringBoot的情况下阻止或防止Spring MVC 4应用程序的XSS

时间:2018-03-19 22:17:00

标签: java spring-mvc xss

如何保护,清理采用原始JSON主体的应用程序,通常输出JSON响应并且不使用Spring Boot。我只看到了一个可能有用的好例子,并使用了JsonComponent。如果我们不使用jsoncomponent,如何过滤掉从整个JSON请求体中删除错误的跨站点脚本标记的请求?此外,可以在请求正文中检测XSS标记并抛出错误。

同时寻找可能保护JSON请求的所有输入/输出并在一个区域中添加该代码的全局解决方案。我们可以使用JSR bean验证,但是我们必须点击所有的define属性和变量。

是否也可以查看可能包含脚本标记的数据的JSON有效负载。

2 个答案:

答案 0 :(得分:1)

首先,防范漏洞的概念与SpringBoot无关,而XSS就是其中一个漏洞。

此漏洞受实施org.springframework.web.filter.OncePerRequestFilter保护,具体取决于您使用的顶级框架&你有什么样的应用程序 - 过滤注册&必须实施链接过程。

想法是简单地清理每个传入的JSON主体&使用已清理的请求主体调用链中的下一个过滤器。

如果您有基于Spring的项目,则应首先尝试使用Spring Security依赖项并启用默认安全功能。 refer this question

对于xss保护,由spring security提供,他们有此免责声明 -

  

请注意,这不是全面的XSS保护!

就我而言,我编写了一个自定义XSS保护过滤器 - org.springframework.web.filter.OncePerRequestFilter

在此过滤器中 - 我使用了此API,

<dependency>
            <groupId>org.owasp.esapi</groupId>
            <artifactId>esapi</artifactId>
</dependency>

在我的代码中,我列出了可能的攻击模式,但我想可能有更好的方法。

在SO上提到这两个以了解我所说的更多内容 - XSS filter to remove all scripts&amp; How to Modify QueryParam and PathParam in Jersey 2

Melardev的回答解释了@RequestParam&amp;的唯一案例。你必须扩展这种方法来处理它的JSON主体的情况。我已经处理了json机构的情况,但由于公司版权,我无法分享我的代码。

答案 1 :(得分:0)

好吧最后我做到了,我发布我的解决方案作为回应而不是评论,它是功能性但不是非常强大,如果你想让我用异常处理程序来改进它让我知道

AntiXssDemoApplication.java是

package com.melardev.stackoverflow.demos.antixssdemo;

import com.melardev.stackoverflow.demos.antixssdemo.filters.AntiXssFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import javax.servlet.Filter;

@SpringBootApplication
@ServletComponentScan
public class AntiXssDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(AntiXssDemoApplication.class, args);
    }

}

AntiXssFilter

package com.melardev.stackoverflow.demos.antixssdemo.filters;

import org.springframework.web.util.HtmlUtils;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter(urlPatterns = "/*")
public class AntiXssFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Filter initialized");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        String userInput = servletRequest.getParameter("param");
        if (userInput != null && !userInput.equalsIgnoreCase(HtmlUtils.htmlEscape(userInput)))
            throw new RuntimeException();
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        System.out.println("destroy");
    }
}

控制器

package com.melardev.stackoverflow.demos.antixssdemo.controllers;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/")
public class HomeController {
    @RequestMapping("/xss-reflected")
    @ResponseBody
    public String xssDemo(@RequestParam("param") String userInput) {
        return userInput;
    }
}

演示:

  1. 在localhost打开浏览器:8080 / xss-reflect?param =看看这个反映的内容,有效!!
  2. 在localhost打开浏览器:8080 / xss-reflect?param =&lt; h1&gt;看看这个反映的内容,有效!!&lt; / h1&gt;
  3. 在第2步,我使用了html标签h2。您应该看到从Filter抛出的Runtime异常,发生的事情是: Filter拦截所有url(因为urlPatterns = / **),为每个拦截调用doFilter,如果用户提供了Html内容,那么HtmlUtils.htmlEscape将返回过滤后的字符串,换句话说,返回的字符串不同于原来的,这意味着用户在他的json输入中提供了Html,这不是我们所期望的,所以我们抛出异常, 如果返回的字符串与htmlEscape(userInput)返回的字符串相同,这意味着用户没有提供任何Html内容,在这种情况下,我们让请求管道像往常一样使用filterChain.doFilter(servletRequest,servletResponse); 我没有使用实时XSS演示,因为chrome很可能会保护你,因为它是任何人都能检测到的非常基本的反射XSS ......

    https://start.spring.io/下载了Spring Boot骨架项目 将Web作为唯一的启动依赖项。

    编辑:改进代码