Struts1 脆弱性対策 

[前の記事][1]

例の件の対処としては不十分だが

リクエストパラメーターの中に特定の文字列が含まれているものを無視する方法

```java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

import org.apache.commons.lang3.StringUtils;
import org.apache.struts.action.ActionServlet;

public class SecureStrutsActioServlet extends ActionServlet {

	String excludes = "class,classLoader,type"; // init param で設定

	@Override
	public void process(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		// TODO 自動生成されたメソッド・スタブ
		super.process(new SecureHttpServletRequest(request), response);
	}

	protected class PackInputStream extends InputStream {

		final InputStream is;
		final OutputStream os;

		public PackInputStream(InputStream is, OutputStream os) {
			super();
			this.is = is;
			this.os = os;
		}

		public int available() throws IOException {
			return is.available();
		}

		public boolean equals(Object arg0) {
			return is.equals(arg0);
		}

		public int hashCode() {
			return is.hashCode();
		}

		public void mark(int arg0) {
			is.mark(arg0);
		}

		public boolean markSupported() {
			return is.markSupported();
		}

		public int read() throws IOException {
			return is.read();
		}

		public int read(byte[] arg0, int arg1, int arg2) throws IOException {
			return is.read(arg0, arg1, arg2);
		}

		public int read(byte[] arg0) throws IOException {
			return is.read(arg0);
		}

		public void reset() throws IOException {
			is.reset();
		}

		public long skip(long arg0) throws IOException {
			return is.skip(arg0);
		}

		public String toString() {
			return is.toString();
		}

		@Override
		public void close() throws IOException {
			is.close();
			os.close();
		}

	}

	protected class SecurePart implements Part {

		final Part part;

		public SecurePart(Part part) {
			this.part = part;
		}

		@Override
		public InputStream getInputStream() throws IOException {
			PackInputStream pcis = null;
			PipedOutputStream pos = new PipedOutputStream();
			PipedInputStream pis = new PipedInputStream(pos);
			try (
					InputStream is = part.getInputStream();
					InputStreamReader isr = new InputStreamReader(is);
					BufferedReader in = new BufferedReader(isr);
					PrintWriter out = new PrintWriter(pos);) {
				pcis = new PackInputStream(pis, pos);

				String line = null;
				loop:
				while ((line = in.readLine()) != null) {
					if (line.indexOf("=") != -1) {
						for (String exclude : excludes.split(",")) {
							if (StringUtils.containsIgnoreCase(line.split("=")[0], exclude)) {
								continue loop;
							}
						}
						out.println(line);
					}
				}
			}
			return pcis;
		}

		@Override
		public String getContentType() {
			return part.getContentType();
		}

		@Override
		public String getName() {
			return part.getName();
		}

		@Override
		public long getSize() {
			return part.getSize();
		}

		@Override
		public void write(String fileName) throws IOException {
			part.write(fileName);
		}

		@Override
		public void delete() throws IOException {
			part.delete();
		}

		@Override
		public String getHeader(String name) {
			return part.getHeader(name);
		}

		@Override
		public Collection<String> getHeaders(String name) {
			return part.getHeaders(name);
		}

		@Override
		public Collection<String> getHeaderNames() {
			return part.getHeaderNames();
		}

	}

	protected class SecureHttpServletRequest extends HttpServletRequestWrapper {

		public SecureHttpServletRequest(HttpServletRequest request) {
			super(request);
		}

		@Override
		public Map<String, String[]> getParameterMap() {
			Map<String, String[]> map = super.getParameterMap();
			Iterator<Map.Entry<String, String[]>> i = map.entrySet().iterator();
			for (; i.hasNext();) {
				Map.Entry<String, String[]> entry = i.next();
				for (String exclude : excludes.split(",")) {
					if (StringUtils.containsIgnoreCase(entry.getKey(), exclude)) {
						i.remove();
					}
				}
			}
			return map;
			return map;
		}

		@Override
		public Enumeration<String> getParameterNames() {
			Enumeration<String> enumeration = super.getParameterNames();
			Vector<String> vector = new Vector<String>();
			loop:
			while (enumeration.hasMoreElements()) {
				String target = enumeration.nextElement();
				for (String exclude : excludes.split(",")) {
					if (StringUtils.containsIgnoreCase(target, exclude)) {
						continue loop;
					}
				}
				vector.addElement(target);
			}
			return vector.elements();
		}

		@Override
		public Collection<Part> getParts() throws IOException, ServletException {
			Collection<Part> parts = super.getParts();
			Set<Part> retParts = new HashSet<>();
			for (Part part : parts) {
				retParts.add(new SecurePart(part));
			}
			return retParts;
		}

		@Override
		public Part getPart(String name) throws IOException, ServletException {
			return new SecurePart(super.getPart(name));
		}

		/*
				@Override
				public String[] getParameterValues(String name) {
					for (String exclude : excludes.split(",")) {
						if (StringUtils.containsIgnoreCase(name, exclude)) {
							return null;
						}
					}
					return super.getParameterValues(name);
				}

				@Override
				public String getParameter(String name) {
					for (String exclude : excludes.split(",")) {
						if (StringUtils.containsIgnoreCase(name, exclude)) {
							return null;
						}
					}
					return super.getParameter(name);
				}
		*/
	}

}

```



[1]: http://qiita.com/asahina_dev/items/39311a83d1efc0a2aecf