摘要: 关于XSS问题的处理,此前在博客 http://blog.csdn.net/catoop/article/details/50338259 中写过处理方法。刚好最近朋友有问到“在Struts2中按文章中那样处理无效”,后来验证了下发现,Struts2 对请求的二次封装有所不同,于是针对Struts.
关于XSS问题的处理,此前在博客 http://blog.csdn.net/catoop/article/details/50338259 中写过处理方法。刚好最近朋友有问到“在Struts2中按文章中那样处理无效”,后来验证了下发现,Struts2 对请求的二次封装有所不同,于是针对Struts2如何处理XSS问题,按照本文的方法可以解决。
其主要思路就是,重写了StrutsPrepareAndExecuteFilter过滤器。
正常情况下我们在web.xml 中配置StrutsPrepareAndExecuteFilter的代码为:
- …………
- <filter>
- <filter-name>struts2</filter-name>
- <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
- </filter>
- …………
将文章后面的几个类保存到项目中后,修改web.xml 的配置,指定我们新的MStrutsPrepareAndExecuteFilter类,代码如下:
- …………
- <filter>
- <filter-name>struts2</filter-name>
- <filter-class>cn.gx.wedding.common.struts2.MStrutsPrepareAndExecuteFilter</filter-class>
- </filter>
- …………
下面是相关的4个类源码(直接下载附件也行)
MDispatcher.java
MMultiPartRequestWrapper.java
MStrutsPrepareAndExecuteFilter.java
MStrutsRequestWrapper.java
这里说明下,因为struts2的源码中这4个类存在紧密的依赖耦合,所以只能把这4个类都重写出来,实际上其中并没有修改什么(详见MMultiPartRequestWrapper.java 和 MStrutsRequestWrapper.java)。
- package cn.gx.wedding.common.struts2;
-
- import java.util.Enumeration;
-
- import javax.servlet.http.HttpServletRequest;
-
- import org.apache.struts2.dispatcher.StrutsRequestWrapper;
-
- import cn.gx.wedding.util.XssShieldUtil;
-
- public class MStrutsRequestWrapper extends StrutsRequestWrapper {
-
- public MStrutsRequestWrapper(HttpServletRequest req) {
- super(req);
- }
-
- public MStrutsRequestWrapper(HttpServletRequest req, boolean bool) {
- super(req, bool);
- }
-
- @Override
- public String getParameter(String name) {
- name = XssShieldUtil.stripXss(name);
- // 返回值之前 先进行过滤
- return XssShieldUtil.stripXss(super.getParameter(name));
- }
-
- @Override
- public String[] getParameterValues(String name) {
- name = XssShieldUtil.stripXss(name);
- // 返回值之前 先进行过滤
- String[] values = super.getParameterValues(name);
- if(values != null){
- for (int i = 0; i < values.length; i++) {
- values[i] = XssShieldUtil.stripXss(values[i]);
- }
- }
- return values;
- }
-
- @Override
- public Enumeration<String> getParameterNames() {
- // Enumeration<String> names = super.getParameterNames();
- // while(names.hasMoreElements()){
- // String name = names.nextElement();
- // name = XssShieldUtil.stripXss(name);
- // }
- // return names;
-
- return super.getParameterNames();
- }
-
- }
- package cn.gx.wedding.common.struts2;
-
- import java.io.File;
- import java.io.IOException;
- import java.util.Map;
-
- import javax.servlet.ServletContext;
- import javax.servlet.http.HttpServletRequest;
-
- import org.apache.struts2.StrutsConstants;
- import org.apache.struts2.dispatcher.Dispatcher;
- import org.apache.struts2.dispatcher.StrutsRequestWrapper;
- import org.apache.struts2.dispatcher.multipart.MultiPartRequest;
- import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper;
-
- import com.opensymphony.xwork2.LocaleProvider;
- import com.opensymphony.xwork2.inject.Inject;
- import com.opensymphony.xwork2.util.logging.Logger;
- import com.opensymphony.xwork2.util.logging.LoggerFactory;
-
- public class MDispatcher extends Dispatcher {
-
- /**
- * Provide a logging instance.
- */
- private static final Logger LOG = LoggerFactory.getLogger(MDispatcher.class);
-
- /**
- * Store state of StrutsConstants.DISABLE_REQUEST_ATTRIBUTE_VALUE_STACK_LOOKUP setting.
- */
- private boolean disableRequestAttributeValueStackLookup;
-
- private ServletContext servletContext;
- private Map<String, String> initParams;
-
- private String multipartSaveDir;
-
- /**
- * Store state of StrutsConstants.STRUTS_DEVMODE setting.
- */
- private boolean devMode;
-
- public MDispatcher(ServletContext servletContext, Map<String, String> initParams) {
- super(servletContext, initParams);
- this.servletContext = servletContext;
- this.initParams = initParams;
- }
-
- @Override
- public HttpServletRequest wrapRequest(HttpServletRequest request, ServletContext servletContext)
- throws IOException {
- // don't wrap more than once
- if (request instanceof StrutsRequestWrapper) {
- return request;
- }
-
- String content_type = request.getContentType();
- if (content_type != null && content_type.contains("multipart/form-data")) {
- MultiPartRequest mpr = getMultiPartRequest();
- LocaleProvider provider = getContainer().getInstance(LocaleProvider.class);
- request = new MMultiPartRequestWrapper(mpr, request, getSaveDir(servletContext), provider);
- } else {
- request = new MStrutsRequestWrapper(request, disableRequestAttributeValueStackLookup);
- }
-
- return request;
- }
-
- private String getSaveDir(ServletContext servletContext) {
- String saveDir = multipartSaveDir.trim();
-
- if (saveDir.equals("")) {
- File tempdir = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
- if (LOG.isInfoEnabled()) {
- LOG.info("Unable to find 'struts.multipart.saveDir' property setting. Defaulting to javax.servlet.context.tempdir");
- }
-
- if (tempdir != null) {
- saveDir = tempdir.toString();
- setMultipartSaveDir(saveDir);
- }
- } else {
- File multipartSaveDir = new File(saveDir);
-
- if (!multipartSaveDir.exists()) {
- if (!multipartSaveDir.mkdirs()) {
- String logMessage;
- try {
- logMessage = "Could not find create multipart save directory '" + multipartSaveDir.getCanonicalPath() + "'.";
- } catch (IOException e) {
- logMessage = "Could not find create multipart save directory '" + multipartSaveDir.toString() + "'.";
- }
- if (devMode) {
- LOG.error(logMessage);
- } else {
- if (LOG.isWarnEnabled()) {
- LOG.warn(logMessage);
- }
- }
- }
- }
- }
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("saveDir=" + saveDir);
- }
-
- return saveDir;
- }
-
- /**
- * Modify state of StrutsConstants.STRUTS_MULTIPART_SAVEDIR setting.
- * @param val New setting
- */
- @Override
- @Inject(StrutsConstants.STRUTS_MULTIPART_SAVEDIR)
- public void setMultipartSaveDir(String val) {
- multipartSaveDir = val;
- }
-
- /**
- * Modify state of StrutsConstants.STRUTS_DEVMODE setting.
- * @param mode New setting
- */
- @Override
- @Inject(StrutsConstants.STRUTS_DEVMODE)
- public void setDevMode(String mode) {
- devMode = "true".equals(mode);
- }
- }
- package cn.gx.wedding.common.struts2;
-
- import java.util.Enumeration;
-
- import javax.servlet.http.HttpServletRequest;
-
- import org.apache.struts2.dispatcher.multipart.MultiPartRequest;
- import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper;
-
- import cn.gx.wedding.util.XssShieldUtil;
-
- import com.opensymphony.xwork2.LocaleProvider;
-
- public class MMultiPartRequestWrapper extends MultiPartRequestWrapper {
-
- public MMultiPartRequestWrapper(MultiPartRequest multiPartRequest, HttpServletRequest request, String saveDir,
- LocaleProvider provider) {
- super(multiPartRequest, request, saveDir, provider);
- }
-
- @Override
- public String getParameter(String name) {
- name = XssShieldUtil.stripXss(name);
- // 返回值之前 先进行过滤
- return XssShieldUtil.stripXss(super.getParameter(name));
- }
-
- @Override
- public String[] getParameterValues(String name) {
- name = XssShieldUtil.stripXss(name);
- // 返回值之前 先进行过滤
- String[] values = super.getParameterValues(name);
- if(values != null){
- for (int i = 0; i < values.length; i++) {
- values[i] = XssShieldUtil.stripXss(values[i]);
- }
- }
- return values;
- }
-
- @Override
- public Enumeration<String> getParameterNames() {
- // Enumeration<String> names = super.getParameterNames();
- // while(names.hasMoreElements()){
- // String name = names.nextElement();
- // name = XssShieldUtil.stripXss(name);
- // }
- // return names;
-
- return super.getParameterNames();
- }
-
- }

- package cn.gx.wedding.common.struts2;
-
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.Map;
-
- import javax.servlet.FilterConfig;
- import javax.servlet.ServletException;
-
- import org.apache.struts2.dispatcher.Dispatcher;
- import org.apache.struts2.dispatcher.ng.ExecuteOperations;
- import org.apache.struts2.dispatcher.ng.HostConfig;
- import org.apache.struts2.dispatcher.ng.InitOperations;
- import org.apache.struts2.dispatcher.ng.PrepareOperations;
- import org.apache.struts2.dispatcher.ng.filter.FilterHostConfig;
- import org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter;
-
- public class MStrutsPrepareAndExecuteFilter extends StrutsPrepareAndExecuteFilter {
-
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- InitOperations init = new InitOperations();
- Dispatcher dispatcher = null;
- try {
- FilterHostConfig config = new FilterHostConfig(filterConfig);
- init.initLogging(config);
- dispatcher = initDispatcher(config);
- init.initStaticContentLoader(config, dispatcher);
-
- prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher);
- execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher);
- this.excludedPatterns = init.buildExcludedPatternsList(dispatcher);
-
- postInit(dispatcher, filterConfig);
- } finally {
- if (dispatcher != null) {
- dispatcher.cleanUpAfterInit();
- }
- init.cleanup();
- }
- }
-
- /**
- * Creates and initializes the dispatcher
- */
- public Dispatcher initDispatcher(HostConfig filterConfig) {
- Dispatcher dispatcher = createDispatcher(filterConfig);
- dispatcher.init();
- return dispatcher;
- }
-
- /**
- * Create a {@link Dispatcher}
- */
- private Dispatcher createDispatcher(HostConfig filterConfig) {
- Map<String, String> params = new HashMap<String, String>();
- for (Iterator e = filterConfig.getInitParameterNames(); e.hasNext();) {
- String name = (String) e.next();
- String value = filterConfig.getInitParameter(name);
- params.put(name, value);
- }
- return new MDispatcher(filterConfig.getServletContext(), params);
- }
- }
如果使用的是springmvc、springboot等其他“非struts2”的框架,请参考 http://blog.csdn.net/catoop/article/details/50338259
原文地址:https://yq.aliyun.com/articles/7126#