企业网站建设的建议,怎样切图做网站,亚洲和欧洲,效果好网站建设哪家好文章目录 前言一、使用注解预防1. 添加依赖2. 自定义注解3. 自定义校验逻辑4. 使用 二、使用过滤器1. 添加配置2. 创建配置类3. 创建过滤器4. 创建过滤器类5. 使用 前言
xss攻击时安全领域中非常常见的一种方法#xff0c;保证我们的系统安全是非常重要的
xss攻击简单来说就… 文章目录 前言一、使用注解预防1. 添加依赖2. 自定义注解3. 自定义校验逻辑4. 使用 二、使用过滤器1. 添加配置2. 创建配置类3. 创建过滤器4. 创建过滤器类5. 使用 前言
xss攻击时安全领域中非常常见的一种方法保证我们的系统安全是非常重要的
xss攻击简单来说就是在用户输入内容中添加脚本 script … script 这里面可能包含获取cookie 一、使用注解预防
1. 添加依赖
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-validation/artifactId
/dependency2. 自定义注解
Retention(RetentionPolicy.RUNTIME)
Target(value {ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
Constraint(validatedBy {XssValidator.class})
public interface Xss {String message() default 不允许任何脚本运行;Class?[] groups() default {};Class? extends Payload[] payload() default {};}3. 自定义校验逻辑
public class XssValidator implements ConstraintValidatorXss, String {Overridepublic boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {// 这里用的hutool的工具类return !ReUtil.contains(HtmlUtil.RE_HTML_MARK, value);}}4. 使用
创建实体类
Data
public class Book {private Long id;private String name;Xssprivate String content;
}创建book控制器
Validated
RestController
RequestMapping(/book)
public class BookController {PostMappingpublic void save(Validated RequestBody Book book){System.out.println(book);}
}发送请求 可以看到系统抛出了异常这样我们就成功了使用注解完成了脚本验证 二、使用过滤器
注解的方式需要一个一个的添加这显然是不太方便的。我们可以通过过滤器的方式对前端传递过来的参数进行统一处理
1. 添加配置
# 防止XSS攻击
xss:# 过滤开关enabled: true# 排除链接多个用逗号分隔excludes: # 匹配链接urlPatterns: /book/*2. 创建配置类
Data
Component
ConfigurationProperties(prefix xss)
public class XssProperties {/*** 过滤开关*/private String enabled;/*** 排除链接多个用逗号分隔*/private String excludes;/*** 匹配链接*/private String urlPatterns;}3. 创建过滤器
Configuration
public class FilterConfig {Autowiredprivate XssProperties xssProperties;// 关闭校验注解SuppressWarnings({rawtypes, unchecked})Bean// xss.enabledtrue时注入beanConditionalOnProperty(value xss.enabled, havingValue true) public FilterRegistrationBean xssFilterRegistration() {// 创建过滤器注册器FilterRegistrationBean registration new FilterRegistrationBean();// 设置运行类型registration.setDispatcherTypes(DispatcherType.REQUEST);// 设置过滤器registration.setFilter(new XssFilter());// 添加拦截路径registration.addUrlPatterns(StrUtil.split(xssProperties.getUrlPatterns(), StrUtil.C_COMMA).toArray(String[]::new));registration.setName(xssFilter);// 设置优先级为最高registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);// 添加自定义参数MapString, String initParameters new HashMapString, String();initParameters.put(excludes, xssProperties.getExcludes());registration.setInitParameters(initParameters);return registration;}
}4. 创建过滤器类
public class XssFilter implements Filter {/*** 排除链接*/public ListString excludes new ArrayList();/*** 初始化的时候将排除连接根据,分割添加到excludes中* param filterConfig* throws ServletException*/Overridepublic void init(FilterConfig filterConfig) throws ServletException {String tempExcludes filterConfig.getInitParameter(excludes);if (StrUtil.isNotBlank(tempExcludes)) {String[] url tempExcludes.split(StrUtil.COMMA);excludes.addAll(Arrays.asList(url));}}Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {HttpServletRequest req (HttpServletRequest) request;HttpServletResponse resp (HttpServletResponse) response;if (handleExcludeURL(req, resp)) {chain.doFilter(request, response);return;}XssHttpServletRequestWrapper xssRequest new XssHttpServletRequestWrapper((HttpServletRequest) request);chain.doFilter(xssRequest, response);}/*** 判断是否为排除过滤路径* param request* param response* return*/private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) {String url request.getServletPath();String method request.getMethod();// GET DELETE 不过滤if (method null || HttpMethod.GET.matches(method) || HttpMethod.DELETE.matches(method)) {return true;}return matches(url, excludes);}public static boolean matches(String str, ListString strs) {if (StrUtil.isBlank(str) || CollUtil.isEmpty(strs)) {return false;}for (String pattern : strs) {if (isMatch(pattern, str)) {return true;}}return false;}public static boolean isMatch(String pattern, String url) {AntPathMatcher matcher new AntPathMatcher();return matcher.match(pattern, url);}Overridepublic void destroy() {}
}public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {/*** param request*/public XssHttpServletRequestWrapper(HttpServletRequest request) {super(request);}/*** 将url拼接的参数进行脚本过滤* param name* return*/Overridepublic String[] getParameterValues(String name) {String[] values super.getParameterValues(name);if (values ! null) {int length values.length;String[] escapesValues new String[length];for (int i 0; i length; i) {// 防xss攻击和过滤前后空格escapesValues[i] HtmlUtil.cleanHtmlTag(values[i]).trim();}return escapesValues;}return super.getParameterValues(name);}/*** 对body的脚本参数进行过滤* return* throws IOException*/Overridepublic ServletInputStream getInputStream() throws IOException {// 非json类型直接返回if (!isJsonRequest()) {return super.getInputStream();}// 为空直接返回String json StrUtil.str(IoUtil.readBytes(super.getInputStream(), false), StandardCharsets.UTF_8);if (StringUtils.isEmpty(json)) {return super.getInputStream();}// xss过滤json HtmlUtil.cleanHtmlTag(json).trim();byte[] jsonBytes json.getBytes(StandardCharsets.UTF_8);final ByteArrayInputStream bis IoUtil.toStream(jsonBytes);return new ServletInputStream() {Overridepublic boolean isFinished() {return true;}Overridepublic boolean isReady() {return true;}Overridepublic int available() throws IOException {return jsonBytes.length;}Overridepublic void setReadListener(ReadListener readListener) {}Overridepublic int read() throws IOException {return bis.read();}};}/*** 是否是Json请求*/public boolean isJsonRequest() {String header super.getHeader(HttpHeaders.CONTENT_TYPE);return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE);}
}5. 使用
发送请求 可以看到传递的脚本被成功过滤掉