Browse Source

open

master
pioneer 3 years ago
commit
e7279d70b2
  1. 6
      README.md
  2. BIN
      doc/JSD-9719-需求确认书V1.docx
  3. 16
      plugin.xml
  4. 37
      src/main/java/com/fr/plugin/SafedConfig.java
  5. 71
      src/main/java/com/fr/plugin/SafedFilter.java
  6. 38
      src/main/java/com/fr/plugin/XssFilterWrapper.java

6
README.md

@ -0,0 +1,6 @@
# open-JSD-9719
JSD-9719 包括但不限于下拉框、下拉复选框、下拉树、单选按钮组、复选按钮组、视图树等控件会出现XSS注入问题,此插件用于对控件输入进行特殊字符过滤\
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\
仅作为开发者学习参考使用!禁止用于任何商业用途!\
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系【pioneer】处理。

BIN
doc/JSD-9719-需求确认书V1.docx

Binary file not shown.

16
plugin.xml

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><plugin>
<id>com.fr.plugin.safe.filter</id>
<name><![CDATA[安全过滤支持插件]]></name>
<active>yes</active>
<version>1.0.1</version>
<env-version>10.0</env-version>
<jartime>2020-07-31</jartime>
<vendor>fr.open</vendor>
<description><![CDATA[安全过滤支持插件]]></description>
<change-notes><![CDATA[
]]></change-notes>
<extra-decision>
<GlobalRequestFilterProvider class="com.fr.plugin.SafedFilter"/>
</extra-decision>
<function-recorder class="com.fr.plugin.SafedFilter"/>
</plugin>

37
src/main/java/com/fr/plugin/SafedConfig.java

@ -0,0 +1,37 @@
package com.fr.plugin;
import com.fr.config.*;
import com.fr.config.holder.Conf;
import com.fr.config.holder.factory.Holders;
@Visualization(category = "安全过滤插件配置")
public class SafedConfig extends DefaultConfiguration {
private static volatile SafedConfig config = null;
public static SafedConfig getInstance() {
if (config == null) {
config = ConfigContext.getConfigInstance(SafedConfig.class);
}
return config;
}
@Identifier(value = "openFlag", name = "开关", description = "开关", status = Status.SHOW)
private Conf<Boolean> openFlag = Holders.simple(true);
public Boolean getOpenFlag() {
return openFlag.get();
}
public void setOpenFlag(Boolean openFlag) {
this.openFlag.set(openFlag);
}
@Override
public Object clone() throws CloneNotSupportedException {
SafedConfig cloned = (SafedConfig) super.clone();
cloned.openFlag = (Conf<Boolean>) openFlag.clone();
return cloned;
}
}

71
src/main/java/com/fr/plugin/SafedFilter.java

@ -0,0 +1,71 @@
package com.fr.plugin;
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.transform.ExecuteFunctionRecord;
import com.fr.plugin.transform.FunctionRecorder;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
@FunctionRecorder(localeKey = "ffff")
public class SafedFilter extends AbstractGlobalRequestFilterProvider {
@Override
public String filterName() {
return "hfLogin";
}
@Override
public String[] urlPatterns() {
return new String[]{
"/*"
};
}
@Override
public void init(FilterConfig filterConfig) {
SafedConfig.getInstance();
FineLoggerFactory.getLogger().info("安全过滤支持插件初始化");
super.init(filterConfig);
}
@Override
@ExecuteFunctionRecord
public void doFilter(HttpServletRequest request, HttpServletResponse httpServletResponse, FilterChain filterChain) {
try {
if (SafedConfig.getInstance().getOpenFlag()) {
if (!isMultipartContent(request)) {
filterChain.doFilter(new XssFilterWrapper(request), httpServletResponse);
return;
}
}
filterChain.doFilter(request, httpServletResponse);
} catch (IOException | ServletException e) {
printException2FrLog(e);
} catch (Exception e) {
printException2FrLog(e);
}
}
private boolean isMultipartContent(HttpServletRequest request) {
if (!"post".equalsIgnoreCase(request.getMethod())) {
return false;
}
String contentType = request.getContentType(); //获取Content-Type
return (contentType != null) && (contentType.toLowerCase().startsWith("multipart/"));
}
public static void printException2FrLog(Throwable e) {
StringWriter writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
String s = writer.toString();
FineLoggerFactory.getLogger().error("错误:{}", s);
}
}

38
src/main/java/com/fr/plugin/XssFilterWrapper.java

@ -0,0 +1,38 @@
package com.fr.plugin;
import com.fr.stable.StringUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class XssFilterWrapper extends HttpServletRequestWrapper {
public XssFilterWrapper(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String name) {
String parameter = super.getParameter(name);
return StringUtils.isNotBlank(parameter) ? htmlEscape(parameter) : parameter;
}
private String htmlEscape(String str) {
return str.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
}
/**
* 对数组参数进行特殊字符过滤
*/
@Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if (values == null) {
return null;
}
String[] newValues = new String[values.length];
for (int i = 0; i < values.length; i++) {
newValues[i] = htmlEscape(values[i]);//spring的HtmlUtils进行转义
}
return newValues;
}
}
Loading…
Cancel
Save