diff --git a/continew-starter-core/src/main/java/top/charles7c/continew/starter/core/constant/PropertiesConstants.java b/continew-starter-core/src/main/java/top/charles7c/continew/starter/core/constant/PropertiesConstants.java index 4fb7dcdc..c1f1ab5d 100644 --- a/continew-starter-core/src/main/java/top/charles7c/continew/starter/core/constant/PropertiesConstants.java +++ b/continew-starter-core/src/main/java/top/charles7c/continew/starter/core/constant/PropertiesConstants.java @@ -79,6 +79,11 @@ public class PropertiesConstants { */ public static final String TRACE = WEB + ".trace"; + /** + * 链路配置 + */ + public static final String XSS = WEB + ".xss"; + /** * 日志配置 */ diff --git a/continew-starter-web/src/main/java/top/charles7c/continew/starter/web/autoconfigure/xss/XssAutoConfiguration.java b/continew-starter-web/src/main/java/top/charles7c/continew/starter/web/autoconfigure/xss/XssAutoConfiguration.java new file mode 100644 index 00000000..228f7ec0 --- /dev/null +++ b/continew-starter-web/src/main/java/top/charles7c/continew/starter/web/autoconfigure/xss/XssAutoConfiguration.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *
+ * http://www.gnu.org/licenses/lgpl.html + *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.web.autoconfigure.xss;
+
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import top.charles7c.continew.starter.core.constant.PropertiesConstants;
+
+/**
+ * XSS配置
+ *
+ * @author whhya
+ * @since 1.0.0
+ */
+@AutoConfiguration
+@ConditionalOnWebApplication
+@ConditionalOnProperty(prefix = PropertiesConstants.XSS, name = PropertiesConstants.ENABLED, havingValue = "true")
+@EnableConfigurationProperties(XssProperties.class)
+public class XssAutoConfiguration {
+ @Bean
+ public FilterRegistrationBean
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.web.autoconfigure.xss;
+
+import cn.hutool.core.collection.CollectionUtil;
+import jakarta.servlet.*;
+import jakarta.servlet.http.HttpServletRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.server.PathContainer;
+import org.springframework.web.util.pattern.PathPattern;
+import org.springframework.web.util.pattern.PathPatternParser;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * xss过滤器
+ *
+ * @author whhya
+ * @since 1.0.0
+ */
+public class XssFilter implements Filter {
+
+ private static final Logger log = LoggerFactory.getLogger(XssFilter.class);
+
+ private final XssProperties xssProperties;
+
+ public XssFilter(XssProperties xssProperties) {
+ this.xssProperties = xssProperties;
+ }
+
+ @Override
+ public void init(FilterConfig filterConfig) {
+ log.debug("[ContiNew Starter] - Auto Configuration 'Web-XssFilter' completed initialization.");
+ }
+
+ @Override
+ public void doFilter(ServletRequest servletRequest,
+ ServletResponse servletResponse,
+ FilterChain filterChain) throws IOException, ServletException {
+ HttpServletRequest req = (HttpServletRequest) servletRequest;
+ //未开启xss过滤,则直接跳过
+ if (!xssProperties.isEnabled()) {
+ filterChain.doFilter(req, servletResponse);
+ return;
+ }
+
+ //限定url地址
+ List
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.web.autoconfigure.xss;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import top.charles7c.continew.starter.core.constant.PropertiesConstants;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * xss配置属性
+ *
+ * @author whhya
+ * @since 1.0.0
+ */
+@ConfigurationProperties(PropertiesConstants.XSS)
+public class XssProperties {
+ /**
+ * 是否启用Xss
+ */
+ private boolean enabled = true;
+
+ /**
+ * 拦截的路由,默认为空
+ */
+ private List
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.web.autoconfigure.xss;
+
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.ArrayUtil;
+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 java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.StringReader;
+
+/**
+ * 针对XssServletRequest进行过滤的包装类
+ *
+ * @author whh
+ * @since 1.0.0
+ */
+public class XssServletRequestWrapper extends HttpServletRequestWrapper {
+
+ private String body = "";
+ String[] method = {"POST", "PATCH", "PUT"};
+
+ public XssServletRequestWrapper(HttpServletRequest request) throws IOException {
+ super(request);
+ if (StrUtil.containsAny(request.getMethod().toUpperCase(), method)) {
+ body = IoUtil.getReader(request.getReader()).readLine();
+ if (StrUtil.isNotEmpty(body)) {
+ body = cleanHtmlTag(body);
+ }
+ }
+
+ }
+
+ @Override
+ public BufferedReader getReader() {
+ return IoUtil.toBuffered(new StringReader(body));
+ }
+
+ @Override
+ public ServletInputStream getInputStream() {
+ return getServletInputStream(body);
+ }
+
+ @Override
+ public String getQueryString() {
+ return cleanHtmlTag(super.getQueryString());
+ }
+
+ @Override
+ public String getParameter(String name) {
+ return cleanHtmlTag(super.getParameter(name));
+ }
+
+ @Override
+ public String[] getParameterValues(String name) {
+ String[] values = super.getParameterValues(name);
+ if (ArrayUtil.isEmpty(values)) {
+ return values;
+ }
+ int length = values.length;
+ String[] escapeValues = new String[length];
+ for (int i = 0; i < length; i++) {
+ escapeValues[i] = cleanHtmlTag(values[i]);
+ }
+ return escapeValues;
+ }
+
+ /**
+ * 清除文本中所有HTML标签,但是不删除标签内的内容
+ *
+ * @param content 文本内容
+ * @return 处理过后的文本
+ */
+ private String cleanHtmlTag(String content) {
+ if (StrUtil.isEmpty(content)) {
+ return content;
+ }
+ return HtmlUtil.cleanHtmlTag(content);
+ }
+
+ static ServletInputStream getServletInputStream(String body) {
+ final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
+ return new ServletInputStream() {
+ public int read() {
+ return byteArrayInputStream.read();
+ }
+
+ @Override
+ public boolean isFinished() {
+ return byteArrayInputStream.available() == 0;
+ }
+
+ @Override
+ public boolean isReady() {
+ return false;
+ }
+
+ @Override
+ public void setReadListener(ReadListener readListener) {
+
+ }
+
+ };
+ }
+}
diff --git a/continew-starter-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/continew-starter-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index ca64d9bb..5be50379 100644
--- a/continew-starter-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/continew-starter-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1,2 +1,3 @@
top.charles7c.continew.starter.web.autoconfigure.cors.CorsAutoConfiguration
-top.charles7c.continew.starter.web.autoconfigure.trace.TraceAutoConfiguration
\ No newline at end of file
+top.charles7c.continew.starter.web.autoconfigure.trace.TraceAutoConfiguration
+top.charles7c.continew.starter.web.autoconfigure.xss.XssAutoConfiguration
\ No newline at end of file