如何防止人们在Spring MVC中执行XSS?

我应该如何防止Spring MVC中的XSS? 现在我只是将所有输出用户文本的位置放到JSTL <c:out>标记或fn:escapeXml()函数中,但这似乎很容易出错,因为我可能会错过一个地方。

有没有一个简单的系统的方法来防止这一点? 也许像一个filter或什么的? 我通过在我的控制器方法上指定@RequestParam参数来收集input。

在Spring中,您可以从<form>标记生成的JSP页面中转义html。 这closures了XSS攻击的很多途径,可以通过三种方式自动完成:

对于web.xml文件中的整个应用程序:

 <context-param> <param-name>defaultHtmlEscape</param-name> <param-value>true</param-value> </context-param> 

对于文件本身给定页面上的所有表单:

 <spring:htmlEscape defaultHtmlEscape="true" /> 

对于每个表单:

 <form:input path="someFormField" htmlEscape="true" /> 

试试XSSFilter 。

当您试图阻止XSS时,重要的是要考虑上下文。 作为一个例子,如果要在JavaScript代码段中的variables中输出数据,而不是在HTML代码或HTML属性中输出数据,那么如何以及如何转义是非常不同的。

我在这里有一个例子: http : //erlend.oftedal.no/blog/?blogid=91

同时签出OWASP XSS预防备忘单: http : //www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet

所以简短的回答是,确保你像Tendayi Mawushebuild议的那样逃避输出,但是当你输出HTML属性或者javascript的时候要格外小心。

我通过@Valid对所有input对象使用Hibernate Validator(binding和@RequestBody json,请参阅https://dzone.com/articles/spring-31-valid-requestbody )。 所以@org.hibernate.validator.constraints.SafeHtml是一个很好的解决scheme。

Hibernate SafeHtmlValidator依赖于org.jsoup ,所以需要添加一个项目依赖项:

 <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.10.1</version> </dependency> 

对于具有字段的bean User

 @NotEmpty @SafeHtml protected String name; 

用控制器中的值<script>alert(123)</script>进行更新尝试

 @PutMapping(value = "/{id}", consumes = MediaType.APPLICATION_JSON_VALUE) public void update(@Valid @RequestBody User user, @PathVariable("id") int id) 

要么

 @PostMapping public void createOrUpdate(@Valid User user) { 

抛出BindException的绑定和MethodArgumentNotValidException @RequestBody与默认消息:

 name may have unsafe html content 

如前所述,Validator也可以用于绑定。 应用程序可以在http://topjava.herokuapp.com/进行testing

你是如何收集用户input的第一个地方? 如果您使用FormController此问题/答案可能会FormController

Spring:绑定到命令时转义input

总是手动检查方法,使用的标签,并确保它们总是逃脱(一次)。 框架在这方面有许多错误和差异。

概述: http : //www.gablog.eu/online/node/91

而不是只依赖于<c:out /> ,还应该使用一个antixss库,这个库不仅可以编码,而且还可以处理input中的恶意脚本。 可用的最好的库之一是OWASP Antisamy ,它非常灵活,可以根据需要进行configuration(使用xml策略文件)。

例如,如果应用程序仅支持文本input,则可以使用由OWASP提供的大多数通用策略文件,该文件可以净化并移除大部分html标记。 同样,如果应用程序支持需要各种html标签的html编辑器(比如tinymce),可以使用更灵活的策略,比如ebay策略文件

 **To avoid XSS security threat in spring application** 

解决XSS问题的方法是在提交表单时过滤表单中的所有文本字段。

  It needs XML entry in the web.xml file & two simple classes. java code :- The code for the first class named CrossScriptingFilter.java is : package com.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import org.apache.log4j.Logger; public class CrossScriptingFilter implements Filter { private static Logger logger = Logger.getLogger(CrossScriptingFilter.class); private FilterConfig filterConfig; public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; } public void destroy() { this.filterConfig = null; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { logger.info("Inlter CrossScriptingFilter ..............."); chain.doFilter(new RequestWrapper((HttpServletRequest) request), response); logger.info("Outlter CrossScriptingFilter ..............."); } } 

名为RequestWrapper.java的第二个类是:

包com.filter;

 import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import org.apache.log4j.Logger; public final class RequestWrapper extends HttpServletRequestWrapper { private static Logger logger = Logger.getLogger(RequestWrapper.class); public RequestWrapper(HttpServletRequest servletRequest) { super(servletRequest); } public String[] getParameterValues(String parameter) { logger.info("InarameterValues .. parameter ......."); String[] values = super.getParameterValues(parameter); if (values == null) { return null; } int count = values.length; String[] encodedValues = new String[count]; for (int i = 0; i < count; i++) { encodedValues[i] = cleanXSS(values[i]); } return encodedValues; } public String getParameter(String parameter) { logger.info("Inarameter .. parameter ......."); String value = super.getParameter(parameter); if (value == null) { return null; } logger.info("Inarameter RequestWrapper ........ value ......."); return cleanXSS(value); } public String getHeader(String name) { logger.info("Ineader .. parameter ......."); String value = super.getHeader(name); if (value == null) return null; logger.info("Ineader RequestWrapper ........... value ...."); return cleanXSS(value); } private String cleanXSS(String value) { // You'll need to remove the spaces from the html entities below logger.info("InnXSS RequestWrapper ..............." + value); //value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;"); //value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;"); //value = value.replaceAll("'", "& #39;"); value = value.replaceAll("eval\\((.*)\\)", ""); value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\""); value = value.replaceAll("(?i)<script.*?>.*?<script.*?>", ""); value = value.replaceAll("(?i)<script.*?>.*?</script.*?>", ""); value = value.replaceAll("(?i)<.*?javascript:.*?>.*?</.*?>", ""); value = value.replaceAll("(?i)<.*?\\s+on.*?>.*?</.*?>", ""); //value = value.replaceAll("<script>", ""); //value = value.replaceAll("</script>", ""); logger.info("OutnXSS RequestWrapper ........ value ......." + value); return value; } 

唯一剩下的就是web.xml文件中的XML条目:

  <filter> <filter-name>XSS</filter-name> <display-name>XSS</display-name> <description></description> <filter-class>com.filter.CrossScriptingFilter</filter-class> </filter> <filter-mapping> <filter-name>XSS</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> 

/ *表示对于浏览器发出的每个请求,都会调用CrossScriptingFilter类。 它将parsing来自请求的所有组件/元素,并将用空stringreplace黑客放置的所有JavaScript标记