java 如何在没有 SpringBoot 的情况下为 Spring MVC 4 应用程序阻止或防止 XSS
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/49373299/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to block or protect against XSS for Spring MVC 4 applications without SpringBoot
提问by Berlin Brown
How do you protect, sanitize applications that take raw JSON bodies and typically output JSON responses and don't use Spring Boot. I only saw one good example that might work and used JsonComponent. If we don't use jsoncomponent, how to filter out a request to remove bad cross site scripting tags from a the entire JSON request body? Also, it would be OK to detect XSS tags in the request body and throw an error.
您如何保护、清理采用原始 JSON 主体并通常输出 JSON 响应且不使用 Spring Boot 的应用程序。我只看到一个很好的例子,它可能工作并使用了 JsonComponent。如果我们不使用 jsoncomponent,如何从整个 JSON 请求正文中过滤掉一个请求以删除错误的跨站点脚本标记?此外,可以在请求正文中检测 XSS 标记并抛出错误。
Also looking for a global solution that might protect all input/output of JSON requests and add that code in one area. We could use JSR bean validation but we would have to hit all of the define properties and variables.
还要寻找一种全局解决方案,可以保护 JSON 请求的所有输入/输出,并将该代码添加到一个区域。我们可以使用 JSR bean 验证,但我们必须点击所有定义的属性和变量。
Is it possible to also look at the JSON payload for data which could include script tags.
是否还可以查看可能包含脚本标签的数据的 JSON 有效负载。
采纳答案by Sabir Khan
First of all , concept to protect against vulnerabilities has nothing to do with SpringBoot and XSS is one of those vulnerabilities.
首先,漏洞防护的概念与SpringBoot无关,XSS就是其中之一。
This vulnerability is protected by implementing a org.springframework.web.filter.OncePerRequestFilter
and depending on which top framework you use & what kind of app you have - filter registration & chaining process has to be implemented.
这个漏洞是通过实施一个来保护的org.springframework.web.filter.OncePerRequestFilter
,这取决于你使用的顶级框架和你拥有的应用程序类型——必须实施过滤器注册和链接过程。
Idea is to simply sanitize every incoming JSON body & call next filter in chain with sanitized request body.
想法是简单地清理每个传入的 JSON 主体并使用清理过的请求主体调用链中的下一个过滤器。
If you have a Spring based project, you should first try to use Spring Security dependencies and enable default security features. refer this question
如果您有一个基于 Spring 的项目,您应该首先尝试使用 Spring Security 依赖项并启用默认安全功能。参考这个问题
For xss protection , offered by spring security they have this disclaimer -
对于由 spring security 提供的 xss 保护,他们有此免责声明 -
Note this is not comprehensive XSS protection!
请注意,这不是全面的 XSS 保护!
In my case, I wrote a custom XSS protection filter implementing - org.springframework.web.filter.OncePerRequestFilter
就我而言,我编写了一个自定义 XSS 保护过滤器,实现 -org.springframework.web.filter.OncePerRequestFilter
In this filter- I have used this API ,
在这个过滤器中 - 我使用了这个 API ,
<dependency>
<groupId>org.owasp.esapi</groupId>
<artifactId>esapi</artifactId>
</dependency>
In my code , I have listed down possible attack patterns but I guess there might be better way to do it.
在我的代码中,我列出了可能的攻击模式,但我想可能有更好的方法来做到这一点。
Refer these two on SO to know more as what I am talking about - XSS filter to remove all scripts& How to Modify QueryParam and PathParam in Jersey 2
请参阅 SO 上的这两个以了解更多我正在谈论的内容 - XSS 过滤器以删除所有脚本以及如何在 Jersey 2 中修改 QueryParam 和 PathParam
Answer by Melardev is explaining the only case for @RequestParam
& you have to extend that approach to handle the case when its a JSON body. I have handled the case of a json body but can't share my code due to company copy right .
Melardev 的回答是解释@RequestParam
& 您必须扩展该方法来处理 JSON 主体的唯一情况。我已经处理了 json 主体的情况,但由于公司版权而无法共享我的代码。
回答by Melardev
Ok finally I did it, I post my solution as response instead of comment, it is functional but no very robust, if you want me to improve it with exception handlers etc let me know
好的,我终于做到了,我发布了我的解决方案作为回应而不是评论,它功能强大但不是很健壮,如果您希望我使用异常处理程序等改进它,请告诉我
The AntiXssDemoApplication.java is
AntiXssDemoApplication.java 是
package com.melardev.stackoverflow.demos.antixssdemo;
包 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);
}
}
the AntiXssFilter
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");
}
}
The Controller
控制器
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;
}
}
The demo:
演示:
- open browser at localhost:8080/xss-reflected?param=Look at this reflected content, works!!
- open browser at localhost:8080/xss-reflected?param=<h1>Look at this reflected content, works!!</h1>
- 在 localhost:8080/xss-reflected 打开浏览器?param=看看这个反映的内容,有效!!
- 在 localhost:8080/xss-reflected 处打开浏览器?param=<h1>看看这个反射的内容,有效!!</h1>
At step 2, I have used the html tag h2. You should see a Runtime exception thrown from Filter, what happened is: The Filter intercepts all urls(because of urlPatterns=/**), for each interception doFilter is called, if the user supplied Html content, then HtmlUtils.htmlEscape will return the filtered string, in other words, the returned string is different from the original one, this means the user supplied Html in his json input, which is not what we expect, so we throw the exception, if the returned string is the same as the string returned by htmlEscape(userInput) this means the user has not supplied any Html content, in that case we let the request pipeline to flow as usual with filterChain.doFilter(servletRequest, servletResponse); I am not using a live XSS demo because chrome will most likely protect you since it is a very basic reflected XSS detected by anyone ...
在第 2 步,我使用了 html 标签 h2。你应该看到一个从Filter抛出的Runtime异常,发生的事情是:Filter拦截所有的urls(因为urlPatterns=/**),对于每次拦截的doFilter被调用,如果用户提供了Html内容,那么HtmlUtils.htmlEscape将返回过滤后的字符串,也就是说返回的字符串和原来的不一样,也就是说用户在他的json输入中提供了Html,这不是我们期望的,所以我们抛出异常,如果返回的字符串和原来的一样由 htmlEscape(userInput) 返回的字符串,这意味着用户没有提供任何 Html 内容,在这种情况下,我们让请求管道像往常一样使用 filterChain.doFilter(servletRequest, servletResponse);
The Spring Boot skeleton project was downloaded from https://start.spring.io/with Web as the only starter dependency.
Spring Boot 框架项目是从https://start.spring.io/下载的 ,Web 作为唯一的启动依赖项。
Edit: Improved code
编辑:改进的代码