1.初始化版本,2.引入thirdpart模块,引入canteen模块,初始化菜品分类,spu
This commit is contained in:
commit
aff77150d6
1595 files changed
+168833
No files matched your search
+79
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net).
|
||||
* <p>
|
||||
* 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
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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 com.bsd.pjcloud.common.xss;
|
||||
|
||||
import com.bsd.pjcloud.common.xss.config.PjcloudXssProperties;
|
||||
import com.bsd.pjcloud.common.xss.core.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* jackson xss 配置
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties(PjcloudXssProperties.class)
|
||||
@ConditionalOnProperty(prefix = PjcloudXssProperties.PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true)
|
||||
public class PjcloudXssAutoConfiguration implements WebMvcConfigurer {
|
||||
|
||||
private final PjcloudXssProperties xssProperties;
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public XssCleaner xssCleaner(PjcloudXssProperties properties) {
|
||||
return new DefaultXssCleaner(properties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public FormXssClean formXssClean(PjcloudXssProperties properties, XssCleaner xssCleaner) {
|
||||
return new FormXssClean(properties, xssCleaner);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Jackson2ObjectMapperBuilderCustomizer xssJacksonCustomizer(PjcloudXssProperties properties,
|
||||
XssCleaner xssCleaner) {
|
||||
JacksonXssClean xssClean = new JacksonXssClean(properties, xssCleaner);
|
||||
return builder -> builder.deserializerByType(String.class, xssClean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
List<String> patterns = xssProperties.getPathPatterns();
|
||||
if (patterns.isEmpty()) {
|
||||
patterns.add("/**");
|
||||
}
|
||||
XssCleanInterceptor interceptor = new XssCleanInterceptor(xssProperties);
|
||||
registry.addInterceptor(interceptor)
|
||||
.addPathPatterns(patterns)
|
||||
.excludePathPatterns(xssProperties.getPathExcludePatterns())
|
||||
.order(Ordered.LOWEST_PRECEDENCE);
|
||||
}
|
||||
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net).
|
||||
* <p>
|
||||
* 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
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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 com.bsd.pjcloud.common.xss.config;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Xss配置类
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@ConfigurationProperties(PjcloudXssProperties.PREFIX)
|
||||
public class PjcloudXssProperties {
|
||||
|
||||
public static final String PREFIX = "security.xss";
|
||||
|
||||
/**
|
||||
* 开启xss,默认关闭: 建议生产环境开启
|
||||
*/
|
||||
private boolean enabled = false;
|
||||
|
||||
/**
|
||||
* 全局:对文件进行首尾 trim
|
||||
*/
|
||||
private boolean trimText = true;
|
||||
|
||||
/**
|
||||
* 模式:clear 清理(默认),escape 转义
|
||||
*/
|
||||
private Mode mode = Mode.clear;
|
||||
|
||||
/**
|
||||
* [clear 专用] prettyPrint,默认关闭: 保留换行
|
||||
*/
|
||||
private boolean prettyPrint = false;
|
||||
|
||||
/**
|
||||
* [clear 专用] 使用转义,默认关闭
|
||||
*/
|
||||
private boolean enableEscape = false;
|
||||
|
||||
/**
|
||||
* 拦截的路由,默认为空
|
||||
*/
|
||||
private List<String> pathPatterns = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 放行的路由,默认为空
|
||||
*/
|
||||
private List<String> pathExcludePatterns = new ArrayList<>();
|
||||
|
||||
public enum Mode {
|
||||
|
||||
/**
|
||||
* 清理
|
||||
*/
|
||||
clear,
|
||||
/**
|
||||
* 转义
|
||||
*/
|
||||
escape;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net).
|
||||
* <p>
|
||||
* 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
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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 com.bsd.pjcloud.common.xss.core;
|
||||
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import com.bsd.pjcloud.common.xss.config.PjcloudXssProperties;
|
||||
import com.bsd.pjcloud.common.xss.utils.XssUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.internal.StringUtil;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Entities;
|
||||
import org.jsoup.safety.Cleaner;
|
||||
import org.springframework.web.util.HtmlUtils;
|
||||
|
||||
/**
|
||||
* 默认的 xss 清理器
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class DefaultXssCleaner implements XssCleaner {
|
||||
|
||||
private final PjcloudXssProperties properties;
|
||||
|
||||
@Override
|
||||
public String clean(String bodyHtml) {
|
||||
// 1. 为空直接返回
|
||||
if (StringUtil.isBlank(bodyHtml)) {
|
||||
return bodyHtml;
|
||||
}
|
||||
PjcloudXssProperties.Mode mode = properties.getMode();
|
||||
if (PjcloudXssProperties.Mode.escape == mode) {
|
||||
// html 转义
|
||||
return HtmlUtils.htmlEscape(bodyHtml, CharsetUtil.UTF_8);
|
||||
}
|
||||
else {
|
||||
// jsoup html 清理
|
||||
Document.OutputSettings outputSettings = new Document.OutputSettings()
|
||||
// 2. 转义,没找到关闭的方法,目前这个规则最少
|
||||
.escapeMode(Entities.EscapeMode.xhtml)
|
||||
// 3. 保留换行
|
||||
.prettyPrint(properties.isPrettyPrint());
|
||||
Document dirty = Jsoup.parseBodyFragment(bodyHtml, "");
|
||||
Cleaner cleaner = new Cleaner(XssUtil.WHITE_LIST);
|
||||
Document clean = cleaner.clean(dirty);
|
||||
clean.outputSettings(outputSettings);
|
||||
// 4. 清理后的 html
|
||||
String escapedHtml = clean.body().html();
|
||||
if (properties.isEnableEscape()) {
|
||||
return escapedHtml;
|
||||
}
|
||||
// 5. 反转义
|
||||
return Entities.unescape(escapedHtml);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net).
|
||||
* <p>
|
||||
* 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
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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 com.bsd.pjcloud.common.xss.core;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.bsd.pjcloud.common.xss.config.PjcloudXssProperties;
|
||||
import com.bsd.pjcloud.common.xss.utils.XssUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.InitBinder;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
|
||||
/**
|
||||
* 表单 xss 处理
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
@ControllerAdvice
|
||||
@RequiredArgsConstructor
|
||||
public class FormXssClean {
|
||||
|
||||
private final PjcloudXssProperties properties;
|
||||
|
||||
private final XssCleaner xssCleaner;
|
||||
|
||||
@InitBinder
|
||||
public void initBinder(WebDataBinder binder) {
|
||||
// 处理前端传来的表单字符串
|
||||
binder.registerCustomEditor(String.class, new StringPropertiesEditor(xssCleaner, properties));
|
||||
}
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public static class StringPropertiesEditor extends PropertyEditorSupport {
|
||||
|
||||
private final XssCleaner xssCleaner;
|
||||
|
||||
private final PjcloudXssProperties properties;
|
||||
|
||||
@Override
|
||||
public String getAsText() {
|
||||
Object value = getValue();
|
||||
return value != null ? value.toString() : StrUtil.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
if (text == null) {
|
||||
setValue(null);
|
||||
}
|
||||
else if (XssHolder.isEnabled()) {
|
||||
String value = xssCleaner.clean(XssUtil.trim(text, properties.isTrimText()));
|
||||
setValue(value);
|
||||
log.debug("Request parameter value:{} cleaned up by mica-xss, current value is:{}.", text, value);
|
||||
}
|
||||
else {
|
||||
setValue(XssUtil.trim(text, properties.isTrimText()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net).
|
||||
* <p>
|
||||
* 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
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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 com.bsd.pjcloud.common.xss.core;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.bsd.pjcloud.common.xss.config.PjcloudXssProperties;
|
||||
import com.bsd.pjcloud.common.xss.utils.XssUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* jackson xss 处理
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class JacksonXssClean extends JsonDeserializer<String> {
|
||||
|
||||
private final PjcloudXssProperties properties;
|
||||
|
||||
private final XssCleaner xssCleaner;
|
||||
|
||||
@Override
|
||||
public String deserialize(JsonParser p, DeserializationContext ctx) throws IOException {
|
||||
// XSS filter
|
||||
String text = p.getValueAsString();
|
||||
if (text == null) {
|
||||
return null;
|
||||
}
|
||||
if (XssHolder.isEnabled()) {
|
||||
String value = xssCleaner.clean(XssUtil.trim(text, properties.isTrimText()));
|
||||
log.debug("Json property value:{} cleaned up by mica-xss, current value is:{}.", text, value);
|
||||
return value;
|
||||
}
|
||||
else {
|
||||
return XssUtil.trim(text, properties.isTrimText());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net).
|
||||
* <p>
|
||||
* 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
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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 com.bsd.pjcloud.common.xss.core;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 忽略 xss
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface XssCleanIgnore {
|
||||
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net).
|
||||
* <p>
|
||||
* 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
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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 com.bsd.pjcloud.common.xss.core;
|
||||
|
||||
import com.bsd.pjcloud.common.xss.config.PjcloudXssProperties;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.AsyncHandlerInterceptor;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* xss 处理拦截器
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class XssCleanInterceptor implements AsyncHandlerInterceptor {
|
||||
|
||||
private final PjcloudXssProperties xssProperties;
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
|
||||
throws Exception {
|
||||
// 1. 非控制器请求直接跳出
|
||||
if (!(handler instanceof HandlerMethod)) {
|
||||
return true;
|
||||
}
|
||||
// 2. 没有开启
|
||||
if (!xssProperties.isEnabled()) {
|
||||
return true;
|
||||
}
|
||||
// 3. 处理 XssIgnore 注解
|
||||
HandlerMethod handlerMethod = (HandlerMethod) handler;
|
||||
XssCleanIgnore xssCleanIgnore = AnnotationUtils.getAnnotation(handlerMethod.getMethod(), XssCleanIgnore.class);
|
||||
if (xssCleanIgnore == null) {
|
||||
XssHolder.setEnable();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
|
||||
throws Exception {
|
||||
XssHolder.remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler)
|
||||
throws Exception {
|
||||
XssHolder.remove();
|
||||
}
|
||||
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net).
|
||||
* <p>
|
||||
* 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
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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 com.bsd.pjcloud.common.xss.core;
|
||||
|
||||
/**
|
||||
* xss 清理器
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
public interface XssCleaner {
|
||||
|
||||
/**
|
||||
* 清理 html
|
||||
* @param html html
|
||||
* @return 清理后的数据
|
||||
*/
|
||||
String clean(String html);
|
||||
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net).
|
||||
* <p>
|
||||
* 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
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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 com.bsd.pjcloud.common.xss.core;
|
||||
|
||||
/**
|
||||
* 利用 ThreadLocal 缓存线程间的数据
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
class XssHolder {
|
||||
|
||||
private static final ThreadLocal<Boolean> TL = new ThreadLocal<>();
|
||||
|
||||
public static boolean isEnabled() {
|
||||
return Boolean.TRUE.equals(TL.get());
|
||||
}
|
||||
|
||||
public static void setEnable() {
|
||||
TL.set(Boolean.TRUE);
|
||||
}
|
||||
|
||||
public static void remove() {
|
||||
TL.remove();
|
||||
}
|
||||
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* 此包代码来源至: https://gitee.com/596392912/mica/tree/master/mica-xss
|
||||
*/
|
||||
package com.bsd.pjcloud.common.xss;
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Michael Yang 杨福海 (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the GNU Lesser General Public License (LGPL) ,Version 3.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
* <p>
|
||||
* 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 com.bsd.pjcloud.common.xss.utils;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Attribute;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* xss clean
|
||||
*
|
||||
* <p>
|
||||
* 参考自 jpress:https://gitee.com/fuhai/jpress
|
||||
* </p>
|
||||
*
|
||||
* @author L.cm
|
||||
* @author michael
|
||||
*/
|
||||
public class XssUtil {
|
||||
|
||||
public static final HtmlWhitelist WHITE_LIST = new HtmlWhitelist();
|
||||
|
||||
/**
|
||||
* trim 字符串
|
||||
* @param text text
|
||||
* @return 清理后的 text
|
||||
*/
|
||||
public static String trim(String text, boolean trim) {
|
||||
return trim ? StringUtils.trimWhitespace(text) : text;
|
||||
}
|
||||
|
||||
/**
|
||||
* xss 清理
|
||||
* @param html html
|
||||
* @return 清理后的 html
|
||||
*/
|
||||
public static String clean(String html) {
|
||||
if (StringUtils.hasText(html)) {
|
||||
return Jsoup.clean(html, WHITE_LIST);
|
||||
}
|
||||
return html;
|
||||
}
|
||||
|
||||
/**
|
||||
* 做自己的白名单,允许base64的图片通过等
|
||||
*
|
||||
* @author michael
|
||||
*/
|
||||
public static class HtmlWhitelist extends org.jsoup.safety.Safelist {
|
||||
|
||||
public HtmlWhitelist() {
|
||||
addTags("a", "b", "blockquote", "br", "caption", "cite", "code", "col", "colgroup", "dd", "div", "span",
|
||||
"embed", "object", "dl", "dt", "em", "h1", "h2", "h3", "h4", "h5", "h6", "i", "img", "li", "ol",
|
||||
"p", "pre", "q", "small", "strike", "strong", "sub", "sup", "table", "tbody", "td", "tfoot", "th",
|
||||
"thead", "tr", "u", "ul");
|
||||
|
||||
addAttributes("a", "href", "title", "target");
|
||||
addAttributes("blockquote", "cite");
|
||||
addAttributes("col", "span");
|
||||
addAttributes("colgroup", "span");
|
||||
addAttributes("img", "align", "alt", "src", "title");
|
||||
addAttributes("ol", "start");
|
||||
addAttributes("q", "cite");
|
||||
addAttributes("table", "summary");
|
||||
addAttributes("td", "abbr", "axis", "colspan", "rowspan", "width");
|
||||
addAttributes("th", "abbr", "axis", "colspan", "rowspan", "scope", "width");
|
||||
addAttributes("video", "src", "autoplay", "controls", "loop", "muted", "poster", "preload");
|
||||
addAttributes("object", "width", "height", "classid", "codebase");
|
||||
addAttributes("param", "name", "value");
|
||||
addAttributes("embed", "src", "quality", "width", "height", "allowFullScreen", "allowScriptAccess",
|
||||
"flashvars", "name", "type", "pluginspage");
|
||||
|
||||
addAttributes(":all", "class", "style", "height", "width", "type", "id", "name");
|
||||
|
||||
addProtocols("blockquote", "cite", "http", "https");
|
||||
addProtocols("cite", "cite", "http", "https");
|
||||
addProtocols("q", "cite", "http", "https");
|
||||
|
||||
// 如果添加以下的协议,那么href 必须是http、 https 等开头,相对路径则被过滤掉了
|
||||
// addProtocols("a", "href", "ftp", "http", "https", "mailto", "tel");
|
||||
|
||||
// 如果添加以下的协议,那么src必须是http 或者 https 开头,相对路径则被过滤掉了,
|
||||
// 所以必须注释掉,允许相对路径的图片资源
|
||||
// addProtocols("img", "src", "http", "https");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSafeAttribute(String tagName, Element el, Attribute attr) {
|
||||
// 不允许 javascript 开头的 src 和 href
|
||||
if ("src".equalsIgnoreCase(attr.getKey()) || "href".equalsIgnoreCase(attr.getKey())) {
|
||||
String value = attr.getValue();
|
||||
if (StringUtils.hasText(value) && value.toLowerCase().startsWith("javascript")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 允许 base64 的图片内容
|
||||
if ("img".equals(tagName) && "src".equals(attr.getKey()) && attr.getValue().startsWith("data:;base64")) {
|
||||
return true;
|
||||
}
|
||||
return super.isSafeAttribute(tagName, el, attr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
com.bsd.pjcloud.common.xss.PjcloudXssAutoConfiguration
|
||||
Reference in new issue
Block a user