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

使用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不存在。

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


撒科打诨
浏览 2130回答 4
4回答

暮色呼如

正如您所指出的HttpServletRequest那样,没有setParameter方法。这是故意的,因为类表示来自客户端的请求,并且修改参数不代表该请求。一种解决方案是使用HttpServletRequestWrapper该类,它允许您将一个请求与另一个请求包装起来。您可以对其进行子类化,并覆盖该getParameter方法以返回已清理的值。然后,您可以将该包装请求传递给chain.doFilter原始请求。它有点难看,但这就是servlet API所说的应该做的事情。如果你试图传递任何其他东西doFilter,一些servlet容器会抱怨你违反了规范,并拒绝处理它。更优雅的解决方案是更多工作 - 修改处理参数的原始servlet / JSP,以便它需要请求属性而不是参数。过滤器检查参数,对其进行清理,并使用request.setAttribute已清理的值设置属性(使用)。没有子类化,没有欺骗,但确实需要您修改应用程序的其他部分。

千巷猫影

为了记录,这是我最后写的课程:import&nbsp;java.io.IOException;import&nbsp;javax.servlet.Filter;import&nbsp;javax.servlet.FilterChain;import&nbsp;javax.servlet.FilterConfig;import&nbsp;javax.servlet.ServletException;import&nbsp;javax.servlet.ServletRequest;import&nbsp;javax.servlet.ServletResponse;import&nbsp;javax.servlet.http.HttpServletRequest;import&nbsp;javax.servlet.http.HttpServletRequestWrapper;public&nbsp;final&nbsp;class&nbsp;XssFilter&nbsp;implements&nbsp;Filter&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;class&nbsp;FilteredRequest&nbsp;extends&nbsp;HttpServletRequestWrapper&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;These&nbsp;are&nbsp;the&nbsp;characters&nbsp;allowed&nbsp;by&nbsp;the&nbsp;Javascript&nbsp;validation&nbsp;*/ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;String&nbsp;allowedChars&nbsp;=&nbsp;"+-0123456789#*"; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;FilteredRequest(ServletRequest&nbsp;request)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super((HttpServletRequest)request); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;String&nbsp;sanitize(String&nbsp;input)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;result&nbsp;=&nbsp;""; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;input.length();&nbsp;i++)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(allowedChars.indexOf(input.charAt(i))&nbsp;>=&nbsp;0)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;+=&nbsp;input.charAt(i); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;result; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;String&nbsp;getParameter(String&nbsp;paramName)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;value&nbsp;=&nbsp;super.getParameter(paramName); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;("dangerousParamName".equals(paramName))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;sanitize(value); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;value; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;String[]&nbsp;getParameterValues(String&nbsp;paramName)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;values[]&nbsp;=&nbsp;super.getParameterValues(paramName); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;("dangerousParamName".equals(paramName))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;index&nbsp;=&nbsp;0;&nbsp;index&nbsp;<&nbsp;values.length;&nbsp;index++)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;values[index]&nbsp;=&nbsp;sanitize(values[index]); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;values; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;doFilter(ServletRequest&nbsp;request,&nbsp;ServletResponse&nbsp;response, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FilterChain&nbsp;chain)&nbsp;throws&nbsp;IOException,&nbsp;ServletException&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chain.doFilter(new&nbsp;FilteredRequest(request),&nbsp;response); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;destroy()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;init(FilterConfig&nbsp;filterConfig)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;}}

湖上湖

编写一个简单的类,该类HttpServletRequestWrapper使用getParameter()方法进行子类化,该方法返回输入的已清理版本。然后通过你的实例HttpServletRequestWrapper来Filter.doChain()直接代替请求对象。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java