【问题标题】:How to change servlet request body in java filter?如何在 java 过滤器中更改 servlet 请求正文?
【发布时间】:2016-03-13 08:22:36
【问题描述】:

如何更改 Java 过滤器中的请求正文以防止 XSS 攻击? 我建立HttpServletRequestWrapper 并使用getparameter 来改变身体但是 获取流关闭异常。

【问题讨论】:

标签: java servlets xss servlet-filters


【解决方案1】:

XSSFilter.java

public class XSSFilter implements Filter {


@Override
public void init(FilterConfig filterConfig) throws ServletException {
}

@Override
public void destroy() {
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {

    XSSRequestWrapper wrappedRequest = new XSSRequestWrapper(
            (HttpServletRequest) request);

    String body = IOUtils.toString(wrappedRequest.getReader());


    if(!"".equals(body))
    {
        JSONObject oldJsonObject = new JSONObject(body);
        JSONObject newJsonObject = new JSONObject();

        for(String key : oldJsonObject.keySet())
        {
            newJsonObject.put(key, XSSUtils.stripXSS(oldJsonObject.get(key).toString()));
        }
        wrappedRequest.resetInputStream(newJsonObject.toString().getBytes());

    }


    chain.doFilter(wrappedRequest, response);
 }
}

XSSRequestWrapper .java

public class XSSRequestWrapper extends HttpServletRequestWrapper {


private byte[] rawData;
private HttpServletRequest request;
private ResettableServletInputStream servletStream;

public XSSRequestWrapper(HttpServletRequest request) {
    super(request);
    this.request = request;
    this.servletStream = new ResettableServletInputStream();
}


public void resetInputStream(byte[] newRawData) {
    servletStream.stream = new ByteArrayInputStream(newRawData);
}

@Override
public ServletInputStream getInputStream() throws IOException {
    if (rawData == null) {
        rawData = IOUtils.toByteArray(this.request.getReader());
        servletStream.stream = new ByteArrayInputStream(rawData);
    }
    return servletStream;
}

@Override
public BufferedReader getReader() throws IOException {
    if (rawData == null) {
        rawData = IOUtils.toByteArray(this.request.getReader());
        servletStream.stream = new ByteArrayInputStream(rawData);
    }
    return new BufferedReader(new InputStreamReader(servletStream));
}

private class ResettableServletInputStream extends ServletInputStream {

    private InputStream stream;

    @Override
    public int read() throws IOException {
        return stream.read();
     }
   }
 }

XSSUtils .java

public class XSSUtils {

private XSSUtils()
{

}

public static String stripXSS(String value) {
    return value == null ? value : escapeHtml4(value);
  }
}

【讨论】:

  • 实际上没有工作。过滤器被调用了,但是body还是原来的那个,getInputStream和getReader方法,还没有调用
【解决方案2】:

由于我没有足够的声誉来添加评论,因此我将其添加为答案。 3 年后,我找到了公认的答案来节省我的时间。同时,我必须解决一些问题,因此添加...

(1) 一个错误(缺少对 rawData 的赋值)

public void resetInputStream(byte[] newRawData) {
    rawData = newRawData;
    servletStream.stream = new ByteArrayInputStream(newRawData);
}

(2) 随着时间的推移需要进行更改。参考: HttpServletRequestWrapper, example implementation for setReadListener / isFinished / isReady?

【讨论】:

  • 欢迎来到 StackOverflow!请花点时间阅读Answering 上的帮助部分。 “由于我没有足够的声誉来添加评论” - 这不是悲剧,因果报应会来找你,记住古老的格言:“潜伏更多”
猜你喜欢
  • 2018-07-31
  • 2018-12-30
  • 2014-09-13
  • 2017-06-19
  • 2011-01-09
  • 2010-11-27
  • 2015-10-28
相关资源
最近更新 更多