面试题答案
一键面试1. 引入依赖
在pom.xml
文件中添加Spring Security相关依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2. 配置Spring Security
创建一个配置类,例如SecurityConfig.java
,继承WebSecurityConfigurerAdapter
:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.web.filter.CharacterEncodingFilter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
filter.setForceEncoding(true);
http.addFilterBefore(filter, CsrfFilter.class);
// 其他配置,如授权规则等
}
}
3. 自定义XSS过滤器
创建一个自定义的XSS过滤器,例如XssFilter.java
:
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
@WebFilter(filterName = "XssFilter", urlPatterns = "/*")
public class XssFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletRequestWrapper wrapper = new XssHttpServletRequestWrapper(request);
filterChain.doFilter(wrapper, servletResponse);
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
同时创建XssHttpServletRequestWrapper.java
来包装请求,对参数进行过滤:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.regex.Pattern;
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
private static final Pattern SCRIPT_PATTERN = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
private static final Pattern STYLE_PATTERN = Pattern.compile("<style>(.*?)</style>", Pattern.CASE_INSENSITIVE);
private static final Pattern HTML_TAG_PATTERN = Pattern.compile("<(.*?)>", Pattern.CASE_INSENSITIVE);
public XssHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
}
@Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if (values != null) {
int length = values.length;
String[] encodedValues = new String[length];
for (int i = 0; i < length; i++) {
encodedValues[i] = cleanXSS(values[i]);
}
return encodedValues;
}
return super.getParameterValues(name);
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
if (value != null) {
return cleanXSS(value);
}
return super.getParameter(name);
}
@Override
public String getHeader(String name) {
String value = super.getHeader(name);
if (value != null) {
return cleanXSS(value);
}
return super.getHeader(name);
}
private String cleanXSS(String value) {
value = SCRIPT_PATTERN.matcher(value).replaceAll("");
value = STYLE_PATTERN.matcher(value).replaceAll("");
value = HTML_TAG_PATTERN.matcher(value).replaceAll("");
return value;
}
}
4. 原理
- Spring Security:它是一个功能强大且高度可定制的安全框架。在配置中,
http.csrf().disable()
是暂时禁用了CSRF(跨站请求伪造)保护,因为这不是防止XSS攻击的直接手段,但可能与XSS过滤配置产生冲突。添加CharacterEncodingFilter
确保请求的编码为UTF - 8,防止因编码问题导致XSS攻击绕过。 - 自定义XSS过滤器:
XssFilter
会在请求到达Servlet之前对其进行拦截。XssHttpServletRequestWrapper
类通过重写getParameterValues
、getParameter
和getHeader
方法,对用户输入的参数和请求头进行过滤。利用正则表达式匹配并替换掉可能包含的XSS脚本标签,从而达到防止XSS攻击的目的。这样在应用处理用户输入之前,恶意脚本就已被清除。