为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

撒科打诨 2019-08-01 15:32:07
使用servlet过滤器修改请求参数现有的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不存在。在将请求传递给链之前,如何更改请求参数的值?
查看完整描述

4 回答

?
暮色呼如

TA贡献1853条经验 获得超9个赞

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

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

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

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


查看完整回答
反对 回复 2019-08-01
?
千巷猫影

TA贡献1829条经验 获得超7个赞

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

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) {
    }}


查看完整回答
反对 回复 2019-08-01
?
湖上湖

TA贡献2003条经验 获得超2个赞

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


查看完整回答
反对 回复 2019-08-01
  • 4 回答
  • 0 关注
  • 2129 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信