我从 Spring 4.2.6.RELEASE 开始使用,后端是休息服务。 现在我无法过滤 Prevent XSS
我的过滤器是:
@Component
@Order(1)
public class XSSFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
@Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(new XSSRequestWrapper((HttpServletRequest) request), response);
}
}
XSSRequestWrapper 是:
public class XSSRequestWrapper extends HttpServletRequestWrapper {
public XSSRequestWrapper(HttpServletRequest servletRequest) {
super(servletRequest);
}
@Override
public String[] getParameterValues(String 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] = stripXSS(values[i]);
}
return encodedValues;
}
@Override
public String getParameter(String parameter) {
String value = super.getParameter(parameter);
return stripXSS(value);
}
@Override
public String getHeader(String name) {
String value = super.getHeader(name);
return stripXSS(value);
}
private String stripXSS(String value) {
return StringEscapeUtils.escapeHtml(value);
}
}
并且在 WebConfig 扩展了 WebMvcConfigurerAdapter 类:
// -----------------------------------------------------
// Prevent XSS
// -----------------------------------------------------
@Bean
public FilterRegistrationBean xssPreventFilter() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new XSSFilter());
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
我的休息课是:
@RestController
@RequestMapping("/personService")
public class PersonController extends BaseController<PersonDto, PersonCriteria> {
@RequestMapping( value= "/test" )
private void getTest2(@RequestParam String name) {
System.out.println(name);
System.out.println( StringEscapeUtils.escapeHtml(name) );
}
}
但是它不起作用,没有任何错误或异常。 我怎样才能做到这一点并创建我自己的过滤器?我只使用 Java Config,不使用 XML。 在我的控制器中,我被迫再次使用 StringEscapeUtils.escapeHtml(name) ,这很糟糕。
我已经根据您的代码创建了一个完全可执行的示例项目。
一切顺利,您可以从我的github下载完整源代码https://github.com/mehditahmasebi/spring/tree/master/spring-xss-filter并运行命令“mvnw spring-boot:run”并在浏览器输入: http://localhost:8080/personService/test?name=foobar,这样你就可以在 XSSRequestWrapper.stripXSS 中看到结果。
希望这个源代码对你有帮助。
一些解释:
项目结构:
深入研究它们,但我只是复制重要的几行:
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
WebConfig.java(在底行你可以看到你的bean):
@Configuration
@EnableWebMvc
@EnableWebSecurity
public class WebConfig extends WebSecurityConfigurerAdapter implements WebMvcConfigurer {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().permitAll()
.and().csrf().disable();
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowCredentials(true)
.allowedHeaders("*")
.allowedMethods("GET, POST, PATCH, PUT, DELETE, OPTIONS")
.allowedOrigins("*");
}
@Bean
public FilterRegistrationBean xssPreventFilter() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new XSSFilter());
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
}
SpringBootApplication.java(用于启动项目):
@SpringBootApplication
public class SpringbootApplication extends SpringBootServletInitializer {
/**
* tomcat deployment needed
*/
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(SpringbootApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
System.out.println("Spring boot application started!");
}
}
其他 java 源文件与您完全相同,但有 2 个更改:
首先,我添加了一条 sysout 行来查看代码的跟踪而无需调试:
private String stripXSS(String value) {
if(value != null)
System.out.println("escapeHTML work successfully and escapeHTML value is : " + StringEscapeUtils.escapeHtml(value));
return StringEscapeUtils.escapeHtml(value);
}
第二个变化是,我从 PersonController 评论了 escapeHtml 正如你所说这不是一个好主意:
@RequestMapping( value= "/test" )
private void getTest2(@RequestParam String name) {
System.out.println(name);
// System.out.println( StringEscapeUtils.escapeHtml(name) );
}
您可以在我的github上找到所有源代码https://github.com/mehditahmasebi/spring/tree/master/spring-xss-filter
一个简单的 XSS 过滤器实现。创建两个分别命名为
XSSFilter
和 XSSRequestWrapper
的 java 类,并分别使用以下实现
package com.example.config;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@Component
@Order(1)
public class XSSFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException{
}
@Override
public void destroy(){
}
@Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException{
chain.doFilter(new XSSRequestWrapper((HttpServletRequest)request),response);
}
}
package com.example.config;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.regex.Pattern;
public class XSSRequestWrapper extends HttpServletRequestWrapper {
private static Pattern[] patterns = new Pattern[]{
Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE),
Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
Pattern.compile("</script>", Pattern.CASE_INSENSITIVE),
Pattern.compile("<script(.*?)>",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
Pattern.compile("eval\\((.*?)\\)",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
Pattern.compile("expression\\((.*?)\\)",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE),
Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE),
Pattern.compile("onload(.*?)=",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL)
};
public XSSRequestWrapper(HttpServletRequest servletRequest) {
super(servletRequest);
}
@Override
public String[] getParameterValues(String 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] = stripXSS(values[i]);
}
return encodedValues;
}
@Override
public String getParameter(String parameter){
String value = super.getParameter(parameter);
return stripXSS(value);
}
@Override
public String getHeader(String name){
String value = super.getHeader(name);
return stripXSS(value);
}
private String stripXSS(String value){
if (value != null){
value = value.replaceAll("\0", "");
for (Pattern scriptPatter: patterns){
value = scriptPatter.matcher(value).replaceAll("");
}
}
return value;
}
}
以下行可以添加到应用程序的
main
类中
@Bean("xssPreventFilter")
public FilterRegistrationBean<XSSFilter> xssFilterFilter(){
FilterRegistrationBean<XSSFilter> registrationBean = new FilterRegistrationBean<XSSFilter>();
registrationBean.setFilter(new XSSFilter());
registrationBean.addUrlPatterns("/*");
return registrationBean;
}