当前位置:  开发笔记 > 编程语言 > 正文

使用servlet过滤器修改请求参数

如何解决《使用servlet过滤器修改请求参数》经验,为你挑选了3个好方法。

现有的Web应用程序正在Tomcat 4.1上运行.页面存在XSS问题,但我无法修改源代码.我决定编写一个servlet过滤器来在页面看到之前清理参数.

我想写一个像这样的Filter类:

import java.io.*;
import javax.servlet.*;

public final class XssFilter implements Filter {

  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException
  {
    String badValue = request.getParameter("dangerousParamName");
    String goodValue = sanitize(badValue);
    request.setParameter("dangerousParamName", goodValue);
    chain.doFilter(request, response);
  }

  public void destroy() {
  }

  public void init(FilterConfig filterConfig) {
  }
}

ServletRequest.setParameter不存在.

在将请求传递给链之前,如何更改请求参数的值?



1> skaffman..:

正如您所指出的HttpServletRequest那样,没有setParameter方法.这是故意的,因为类表示来自客户端的请求,并且修改参数不代表该请求.

一种解决方案是使用HttpServletRequestWrapper该类,它允许您将一个请求与另一个请求包装起来.您可以对其进行子类化,并覆盖该getParameter方法以返回已清理的值.然后,您可以将该包装请求传递给chain.doFilter原始请求.

它有点难看,但这就是servlet API所说的应该做的事情.如果你试图传递任何其他东西doFilter,一些servlet容器会抱怨你违反了规范,并拒绝处理它.

更优雅的解决方案是更多工作 - 修改处理参数的原始servlet/JSP,以便它需要请求属性而不是参数.过滤器检查参数,对其进行清理,并使用request.setAttribute已清理的值设置属性(使用).没有子类化,没有欺骗,但确实需要您修改应用程序的其他部分.


HttpServletRequestWrapper太棒了; 我从来不知道它存在.谢谢!
感谢您选择属性设置!使用Head First Servlets和JSP中的请求和响应包装器看到示例代码,并且无法相信该规范会推动人们以这种方式进行操作.

2> Jeremy Stein..:

为了记录,这是我最后写的课程:

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public final class XssFilter implements Filter {

    static class FilteredRequest extends HttpServletRequestWrapper {

        /* These are the characters allowed by the Javascript validation */
        static String allowedChars = "+-0123456789#*";

        public FilteredRequest(ServletRequest request) {
            super((HttpServletRequest)request);
        }

        public String sanitize(String input) {
            String result = "";
            for (int i = 0; i < input.length(); i++) {
                if (allowedChars.indexOf(input.charAt(i)) >= 0) {
                    result += input.charAt(i);
                }
            }
            return result;
        }

        public String getParameter(String paramName) {
            String value = super.getParameter(paramName);
            if ("dangerousParamName".equals(paramName)) {
                value = sanitize(value);
            }
            return value;
        }

        public String[] getParameterValues(String paramName) {
            String values[] = super.getParameterValues(paramName);
            if ("dangerousParamName".equals(paramName)) {
                for (int index = 0; index < values.length; index++) {
                    values[index] = sanitize(values[index]);
                }
            }
            return values;
        }
    }

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        chain.doFilter(new FilteredRequest(request), response);
    }

    public void destroy() {
    }

    public void init(FilterConfig filterConfig) {
    }
}


看起来我是下一个人,杰里米.我在寻找修改从外部应用程序传递到第三方servlet的数据的选项时发现了这篇文章.在我的例子中,servlet没有调用HTTPServletRequest.getParameter(),getParameterMap(),甚至的getAttribute()来获得请求的数据,所以,通过试验和错误,我确定了servlet在呼唤HTTPServletRequest.getInputStream()和getQueryString().我对任何为封闭的servlet尝试此任务的人的建议是将每个访问者包装在HTTPServletRequest中,以便了解真正发生的事情.
您可能还需要考虑getParameterMap方法.也许抛出和不支持的异常只是因为没有组件使用该方法并跳过清理逻辑.
对于SrpingMVC,您需要覆盖getParameterValues()来欺骗Spring.RequestParamMethodArgumentResolver.resovleName()使用该方法,因此您将获得MissingServletRequestParameterException而不会覆盖.使用spring-web 4.1.7在Spring Boot 1.2.6上测试.

3> Asaph..:

编写一个简单的类,该类HttpServletRequestWrapper使用getParameter()方法进行子类化,该方法返回输入的已清理版本.然后通过你的实例HttpServletRequestWrapperFilter.doChain()直接代替请求对象.

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有