Uploaded image for project: 'Wink'
  1. Wink
  2. WINK-439

@FormParam-annotated parameters may be URL decoded twice

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Minor
    • Resolution: Unresolved
    • 1.4
    • None
    • Server
    • None
    • Jetty 9.2.9.v20150224

    Description

      I suspect there is a defect in the org.apache.wink.server.internal.registry.ServerInjectableFactory$FormParamBinding.getValue() method [1] that causes @FormParam-annotated parameters to be URL decoded twice under certain conditions. This causes a problem when the unencoded parameter value contains a percent sign (%). In that case, the second URL decode incorrectly transforms sequences of %<char><char> into a single character resulting in an incorrect parameter value on the service side.

      The issue is manifested when the path through FormParamBinding.getValue() goes through the following code:

                          // see E011 at
                          // http://jcp.org/aboutJava/communityprocess/maintenance/jsr311/311ChangeLog.html
                          // Perhaps the message body was already consumed by a
                          // servlet filter. Let's try the servlet request parameters
                          // instead.
                          Map map =
                              RuntimeContextTLS.getRuntimeContext()
                                  .getAttribute(HttpServletRequest.class).getParameterMap();
      

      The javax.servlet.ServletRequest.getParameterMap() method will URL decode the parameter value if the content type is application/x-www-form-urlencoded (this is not specified in the Javadocs, but I confirmed that Jetty implements this behavior). Then, regardless of how the parameter value was retrieved, the following code is executed later in the method:

                  // decode all values
                  decodeValues(values);
      

      The decodeValues() method also URL decodes the parameter value.

      Thus, the parameter value is URL decoded twice whenever Wink is forced to retrieve the parameter value from the request object instead of reading the request body directly.

      A naive fix for the issue would be to bypass decodeValues() if the parameter value is obtained from the request object.

      A confirmed workaround for the issue requires replacing the @FormParam-annotated parameter(s) of the service method with a @Context-annotated parameter referencing the HttpServletRequest and directly retrieving the form parameters from the request object. A possible, but unconfirmed, workaround may be to annotate the service method with @Encoded to suppress one of the URL decodes [2].

      [1] http://svn.apache.org/viewvc/wink/tags/wink-1.4.0/wink-server/src/main/java/org/apache/wink/server/internal/registry/ServerInjectableFactory.java?revision=1523533&view=markup#l342
      [2] http://stackoverflow.com/a/11949673/3900879

      Attachments

        1. test-case.patch
          9 kB
          Steven Soloff

        Activity

          People

            Unassigned Unassigned
            ssoloff Steven Soloff
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated: