-
Notifications
You must be signed in to change notification settings - Fork 238
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix 修复 经过加密的请求无法过滤xss问题 将xss实现从gateway移动到common-web解密后过滤
- Loading branch information
1 parent
f64b17b
commit 503a0ef
Showing
8 changed files
with
209 additions
and
113 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/FilterConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package org.dromara.common.web.config; | ||
|
||
import jakarta.servlet.DispatcherType; | ||
import org.dromara.common.web.config.properties.XssProperties; | ||
import org.dromara.common.web.filter.XssFilter; | ||
import org.springframework.boot.autoconfigure.AutoConfiguration; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||
import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||
import org.springframework.boot.web.servlet.FilterRegistrationBean; | ||
import org.springframework.context.annotation.Bean; | ||
|
||
/** | ||
* Filter配置 | ||
* | ||
* @author Lion Li | ||
*/ | ||
@AutoConfiguration | ||
@EnableConfigurationProperties(XssProperties.class) | ||
public class FilterConfig { | ||
|
||
@Bean | ||
@ConditionalOnProperty(value = "xss.enabled", havingValue = "true") | ||
public FilterRegistrationBean<XssFilter> xssFilterRegistration() { | ||
FilterRegistrationBean<XssFilter> registration = new FilterRegistrationBean<>(); | ||
registration.setDispatcherTypes(DispatcherType.REQUEST); | ||
registration.setFilter(new XssFilter()); | ||
registration.addUrlPatterns("/*"); | ||
registration.setName("xssFilter"); | ||
registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE + 1); | ||
return registration; | ||
} | ||
|
||
} |
8 changes: 3 additions & 5 deletions
8
...eway/config/properties/XssProperties.java → .../web/config/properties/XssProperties.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/filter/XssFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package org.dromara.common.web.filter; | ||
|
||
import jakarta.servlet.*; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import jakarta.servlet.http.HttpServletResponse; | ||
import org.dromara.common.core.utils.SpringUtils; | ||
import org.dromara.common.core.utils.StringUtils; | ||
import org.dromara.common.web.config.properties.XssProperties; | ||
import org.springframework.http.HttpMethod; | ||
|
||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
/** | ||
* 防止XSS攻击的过滤器 | ||
* | ||
* @author ruoyi | ||
*/ | ||
public class XssFilter implements Filter { | ||
/** | ||
* 排除链接 | ||
*/ | ||
public List<String> excludes = new ArrayList<>(); | ||
|
||
@Override | ||
public void init(FilterConfig filterConfig) throws ServletException { | ||
XssProperties properties = SpringUtils.getBean(XssProperties.class); | ||
String appName = SpringUtils.getApplicationName(); | ||
String appPath = "/" + StringUtils.substring(appName, appName.indexOf("-") + 1); | ||
List<String> excludeUrls = properties.getExcludeUrls() | ||
.stream() | ||
.filter(x -> StringUtils.startsWith(x, appPath)) | ||
.map(x -> x.replaceFirst(appPath, StringUtils.EMPTY)) | ||
.toList(); | ||
excludes.addAll(excludeUrls); | ||
} | ||
|
||
@Override | ||
public 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); | ||
} | ||
|
||
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 StringUtils.matches(url, excludes); | ||
} | ||
|
||
@Override | ||
public void destroy() { | ||
|
||
} | ||
} |
97 changes: 97 additions & 0 deletions
97
...-common-web/src/main/java/org/dromara/common/web/filter/XssHttpServletRequestWrapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package org.dromara.common.web.filter; | ||
|
||
import cn.hutool.core.io.IoUtil; | ||
import cn.hutool.core.util.StrUtil; | ||
import cn.hutool.http.HtmlUtil; | ||
import jakarta.servlet.ReadListener; | ||
import jakarta.servlet.ServletInputStream; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import jakarta.servlet.http.HttpServletRequestWrapper; | ||
import org.dromara.common.core.utils.StringUtils; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.http.MediaType; | ||
|
||
import java.io.ByteArrayInputStream; | ||
import java.io.IOException; | ||
import java.nio.charset.StandardCharsets; | ||
|
||
/** | ||
* XSS过滤处理 | ||
* | ||
* @author ruoyi | ||
*/ | ||
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { | ||
/** | ||
* @param request | ||
*/ | ||
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[] escapseValues = new String[length]; | ||
for (int i = 0; i < length; i++) { | ||
// 防xss攻击和过滤前后空格 | ||
escapseValues[i] = HtmlUtil.cleanHtmlTag(values[i]).trim(); | ||
} | ||
return escapseValues; | ||
} | ||
return super.getParameterValues(name); | ||
} | ||
|
||
@Override | ||
public 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() { | ||
@Override | ||
public boolean isFinished() { | ||
return true; | ||
} | ||
|
||
@Override | ||
public boolean isReady() { | ||
return true; | ||
} | ||
|
||
@Override | ||
public int available() throws IOException { | ||
return jsonBytes.length; | ||
} | ||
|
||
@Override | ||
public void setReadListener(ReadListener readListener) { | ||
} | ||
|
||
@Override | ||
public 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); | ||
} | ||
} |
3 changes: 2 additions & 1 deletion
3
...esources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
org.dromara.common.web.config.FilterConfig | ||
org.dromara.common.web.config.I18nConfig | ||
org.dromara.common.web.config.UndertowConfig | ||
org.dromara.common.web.config.ResourcesConfig | ||
org.dromara.common.web.config.ResourcesConfig |
100 changes: 0 additions & 100 deletions
100
ruoyi-gateway/src/main/java/org/dromara/gateway/filter/XssFilter.java
This file was deleted.
Oops, something went wrong.