【问题标题】:How to block or protect against XSS for Spring MVC 4 applications without SpringBoot如何在没有 Spring Boot 的情况下阻止或防止 Spring MVC 4 应用程序的 XSS
【发布时间】:2018-03-19 22:16:59
【问题描述】:

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

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

是否还可以查看 JSON 有效负载以获取可能包含脚本标签的数据。

【问题讨论】:

  • 嗨,HtmlUtils.htmlEscape(yourDangerousString) docs.spring.io/spring/docs/current/javadoc-api/org/… 这个方法做了一些过滤,如果你有兴趣阻止然后你检查 if(yourDangerousString.equals(HtmlUtils.htmlEscape(yourDangerousString))return ResponseEntity.status(HttpStatus.BAD_REQUEST);
  • 您还有更多代码吗?你如何使用它?正在寻找一种可以保护整个网站的全球解决方案。
  • 我第一次在谷歌上寻找例子是programcreek.com/java-api-examples/…,没什么好说的,你在你的过滤器中放了一个这样的电话,应该就是这样,你真的需要我吗为你写一个工作演示?如果您不能自己做,请告诉我是否要我做

标签: java spring-mvc xss


【解决方案1】:

好吧,我终于做到了,我将我的解决方案发布为响应而不是评论,它功能强大但不是很强大,如果您希望我使用异常处理程序等改进它,请告诉我

AntiXssDemoApplication.java 是

包 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-reflected?param=看这个反射的内容,工作!
  2. 在 localhost:8080/xss-reflected 处打开浏览器?param=

    看看这个反射的内容,工作!!

在第 2 步,我使用了 html 标签 h2。您应该会看到从 Filter 抛出的运行时异常,发生的情况是: Filter会拦截所有的url(因为urlPatterns=/**),每次拦截都会调用doFilter,如果用户提供了Html内容,那么HtmlUtils.htmlEscape会返回过滤后的字符串,也就是说返回的字符串与原始的,这意味着用户在他的 json 输入中提供了 Html,这不是我们所期望的,所以我们抛出异常, 如果返回的字符串与 htmlEscape(userInput) 返回的字符串相同,这意味着用户没有提供任何 Html 内容,在这种情况下,我们让请求管道像往常一样使用 filterChain.doFilter(servletRequest, servletResponse); 我没有使用现场 XSS 演示,因为 chrome 很可能会保护您,因为它是任何人都可以检测到的非常基本的反射型 XSS ...

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

编辑:改进的代码

【讨论】:

  • 这是否适用于 JSON 有效负载作为原始请求正文?
  • @BerlinBrown 为什么不呢?您可以 request.getInputStream(),然后将其存储到 String,然后调用 HtmlUtils.htmlEscape(),将流转换为 String,您可以使用 Apache Commons,如下所示: String requestBody = IOUtils.toString(request.getInputStream(),编码);然后你 htmlEscape(requestBody)
  • Html 字符可以在其他上下文中显示为有效数据。在 JSON 输入中特别需要引号字符,此方法将拒绝该字符。
  • 没错,我目前状态下的demo并不适合所有情况,我的demo限制性太强。但是您可以轻松地在顶部添加一些代码而不抛出异常,而只需对用户输入进行编码。这是大多数开发人员所做的
  • 如何防止文件(多部分)。任何建议
【解决方案2】:

首先,防止漏洞的概念与 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 scriptsHow to Modify QueryParam and PathParam in Jersey 2

Melardev 的回答正在解释 @RequestParam 的唯一情况,您必须扩展该方法以处理 JSON 正文的情况。我已经处理了 json body 的情况,但由于公司版权无法分享我的代码。

【讨论】:

    猜你喜欢
    • 2018-05-15
    • 2018-07-12
    • 2018-04-01
    • 2017-06-15
    • 2018-08-27
    • 2018-04-15
    • 2020-12-23
    • 2011-01-10
    • 2016-06-01
    相关资源
    最近更新 更多