什么是XSS攻击?
xss攻击是指有人恶意编写了一段脚本链接,当用户点击的时候就会向用户所在的服务器发送一个请求,这个请求包含了一段js代码,如果不防止xss那么这段js代码会被执行,这样子后果十分严重,容易被篡改数据和像数据库插入一条恶意数据。
package com.ktjy.ktds.common.config.xss;import cn.hutool.core.util.StrUtil; import cn.hutool.http.HtmlUtil; import cn.hutool.json.JSONUtil;import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.io.*; import java.nio.charset.Charset; import java.util.LinkedHashMap; import java.util.Map;/*** XSS攻击防护请求包装类* 该类继承自HttpServletRequestWrapper,用于过滤请求参数、头部等中的HTML标签,* 以防止跨站脚本(XSS)攻击。通过移除或清理输入中的HTML标签,可以有效减少恶意脚本注入的风险。*/ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {/*** 构造方法,初始化父类并包装传入的HttpServletRequest对象。** @param request 被包装的HttpServletRequest对象*/public XssHttpServletRequestWrapper(HttpServletRequest request) {super(request);}/*** 重写getParameter方法,过滤单个输入参数中的HTML标签。* 如果参数值不为空,则使用HtmlUtil.cleanHtmlTag方法清除其中的HTML标签。** @param name 参数名* @return 过滤后的参数值*/@Overridepublic String getParameter(String name) {String value = super.getParameter(name);if (!StrUtil.hasEmpty(value)) {// 清除HTML标签value = HtmlUtil.cleanHtmlTag(value);}return value;}/*** 重写getParameterValues方法,过滤多个输入参数中的HTML标签。* 对于非空的参数值数组,逐个元素进行HTML标签清除。** @param name 参数名* @return 过滤后的参数值数组*/@Overridepublic String[] getParameterValues(String name) {String[] values = super.getParameterValues(name);if (values != null) {for (int i = 0; i < values.length; i++) {String value = values[i];if (!StrUtil.hasEmpty(value)) {// 清除HTML标签value = HtmlUtil.cleanHtmlTag(value);}values[i] = value;}}return values;}/*** 重写getParameterMap方法,过滤整个参数映射中的HTML标签。* 遍历所有参数键值对,对非空的字符串值进行HTML标签清除,并返回新的参数映射。** @return 过滤后的参数映射*/@Overridepublic Map<String, String[]> getParameterMap() {Map<String, String[]> parameters = super.getParameterMap();LinkedHashMap<String, String[]> map = new LinkedHashMap<>();if (parameters != null) {for (String key : parameters.keySet()) {String[] values = parameters.get(key);for (int i = 0; i < values.length; i++) {String value = values[i];if (!StrUtil.hasEmpty(value)) {// 清除HTML标签value = HtmlUtil.cleanHtmlTag(value);}values[i] = value;}map.put(key, values);}}return map;}/*** 重写getHeader方法,过滤请求头中的HTML标签。* 如果请求头值不为空,则使用HtmlUtil.cleanHtmlTag方法清除其中的HTML标签。** @param name 请求头名* @return 过滤后的请求头值*/@Overridepublic String getHeader(String name) {String value = super.getHeader(name);if (!StrUtil.hasEmpty(value)) {// 清除HTML标签value = HtmlUtil.cleanHtmlTag(value);}return value;}/*** 重写getInputStream方法,用于过滤请求体中的HTML标签。* 读取请求体内容,解析为JSON对象,对其中的字符串值进行HTML标签清除,再转换回JSON字符串并返回新的输入流。** @return 过滤后的请求体输入流* @throws IOException 当读取请求体时发生I/O错误*/@Overridepublic ServletInputStream getInputStream() throws IOException {// 读取原始请求体内容InputStream in = super.getInputStream();InputStreamReader reader = new InputStreamReader(in, Charset.forName("UTF-8"));BufferedReader buffer = new BufferedReader(reader);StringBuffer body = new StringBuffer();String line = buffer.readLine();while (line != null) {body.append(line);line = buffer.readLine();}buffer.close();reader.close();in.close();// 解析请求体为JSON对象Map<String, Object> map = JSONUtil.parseObj(body.toString());Map<String, Object> result = new LinkedHashMap<>();// 对JSON对象中的字符串值进行HTML标签清除for (String key : map.keySet()) {Object val = map.get(key);if (val instanceof String) {if (!StrUtil.hasEmpty(val.toString())) {result.put(key, HtmlUtil.cleanHtmlTag(val.toString()));} else {result.put(key, val);}} else {result.put(key, val);}}// 将处理后的JSON对象转换为字符串并创建新的输入流String json = JSONUtil.toJsonStr(result);ByteArrayInputStream bain = new ByteArrayInputStream(json.getBytes());// 返回新的ServletInputStream实现return new ServletInputStream() {@Overridepublic int read() throws IOException {return bain.read();}@Overridepublic boolean isFinished() {return false;}@Overridepublic boolean isReady() {return false;}@Overridepublic void setReadListener(ReadListener readListener) {// 不需要实现}};} }
允许跨域
package com.ktjy.ktds.common.config;import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** 跨域请求配置类* 通过实现WebMvcConfigurer接口,自定义Spring MVC的配置* 主要用于解决前后端分离项目中的跨域请求问题*/ @Configuration public class CorsConfig implements WebMvcConfigurer {/*** 添加跨域映射配置* 该方法用于配置跨域请求的规则,使得指定的URL路径支持跨域请求* * @param registry CorsRegistry对象,用于注册跨域映射规则*/@Overridepublic void addCorsMappings(CorsRegistry registry) {// 配置跨域请求的映射路径,"/**"表示所有路径都支持跨域请求// allowedOrigins("*")表示允许所有来源的跨域请求// allowCredentials(true)表示支持携带凭据的跨域请求// allowedMethods指定允许的跨域请求方法// maxAge(3600)表示预检请求的缓存时间(秒)registry.addMapping("/**").allowedOrigins("*").allowCredentials(true).allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH").maxAge(3600);} }