Spring Security
  1. Spring Security
  2. SEC-1584

Path parameters should be stripped from pathInfo and servletPath before matching

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: 2.0.5, 3.0.3, 3.1.0.M1
    • Fix Version/s: 3.0.4, 2.0.6, 3.1.0.M2
    • Component/s: Web
    • Labels:
      None

      Description

      RFC 2396 defines parameters which can occur in any of the path segments of a URL, after a semi-colon character. The servlet spec refers to these as "path parameters" and is not consistent on whether they should be removed from the decoded values returned by HttpServletRequest,getServletPath() and HttpServletRequest,getPathInfo(). As a result, different servlet containers treat the issue differently. Tomcat does not include path parameter values, but Websphere apparently does.

      Path parameters should be removed before matching against a secured Ant path pattern (which uses the concatenated servletPath + pathInfo). They complicate the process of pattern matching and make it harder to account for all possible URL values which an attacker could submit. In practice they are rarely used within an application, though most users will be familiar with the addition of a jsessionid parameter to URLs.

      As an example, if an application defined a secured path as "/secure/*", then to account for the possibility of path parameters, the pattern would actually have to be "/secure/**", otherwise a path such as "/secure;x=y/file" could be used to bypass the match. In cases where a trailing wildcard is not used, it could be possible to add a parameter which caused a different match to take place. For example with this configuration:

      <intercept-url path="*user.jsp" access="user" />
      <intercept-url path="/admin/**" access="admin" /> 
      

      A user could potentially gain admin access by submitting a request to "/admin/securedFile.jsp;x=user.jsp".

        Activity

        Hide
        Luke Taylor added a comment - - edited

        RFC 2396 has been superseded by RFC 3986 which no longer refers explicitly to parameters in the definition of a URI, other than to say:

        "URI producing applications often use the reserved characters allowed in a segment to delimit scheme-specific or dereference-handler-specific subcomponents.  For example, the semicolon (";") and equals ("=") reserved characters are often used to delimit parameters and parameter values applicable to that segment."

        So in theory one or more semi-colons can occur in a path segment, without being regarded as a delimiter for parameters. However, for the specific case of HTTP URLs, which is most relevant here, RFC 2616 still uses the path definitions from RFC 2396. The likelihood of having un-encoded semi-colons in a URL which are required by the application seems very slim and is outweighed by the risks defined above, so stripping out strings following a semi-colon still seems like the best option.

        Show
        Luke Taylor added a comment - - edited RFC 2396 has been superseded by RFC 3986 which no longer refers explicitly to parameters in the definition of a URI, other than to say: "URI producing applications often use the reserved characters allowed in a segment to delimit scheme-specific or dereference-handler-specific subcomponents.  For example, the semicolon (";") and equals ("=") reserved characters are often used to delimit parameters and parameter values applicable to that segment." So in theory one or more semi-colons can occur in a path segment, without being regarded as a delimiter for parameters. However, for the specific case of HTTP URLs, which is most relevant here, RFC 2616 still uses the path definitions from RFC 2396. The likelihood of having un-encoded semi-colons in a URL which are required by the application seems very slim and is outweighed by the risks defined above, so stripping out strings following a semi-colon still seems like the best option.
        Hide
        Luke Taylor added a comment -

        Investigating this further, there are other possible areas where containers interpret URIs differently. For example, Tomcat and Jetty will both normalize the URI to obtain the servletPath and pathInfo, whereas Websphere retains path traversal sequences (such as "/./" and "/../"). So for two servlet mappings "/admin/" and "/user/" WAS will map the request URI "/admin/../user/blah" to the "/admin" servlet, whereas both Tomcat and Jetty would use the "/user" mapping. A configuration parameter (com.ibm.ws.webcontainer.normalizerequesturi) has been introduced to in WAS to override this behaviour. There is no good reason I can think of why Spring Security applications should need to use unnormalized request URIs, so we should probably reject these by default to be on the safe side.

        Another thing which might affect pattern matching is the use of multiple "/" characters. Tomcat strips these out, but other containers may not. We should also strip these for matching.

        Show
        Luke Taylor added a comment - Investigating this further, there are other possible areas where containers interpret URIs differently. For example, Tomcat and Jetty will both normalize the URI to obtain the servletPath and pathInfo, whereas Websphere retains path traversal sequences (such as "/./" and "/../"). So for two servlet mappings "/admin/ " and "/user/ " WAS will map the request URI "/admin/../user/blah" to the "/admin" servlet, whereas both Tomcat and Jetty would use the "/user" mapping. A configuration parameter (com.ibm.ws.webcontainer.normalizerequesturi) has been introduced to in WAS to override this behaviour. There is no good reason I can think of why Spring Security applications should need to use unnormalized request URIs, so we should probably reject these by default to be on the safe side. Another thing which might affect pattern matching is the use of multiple "/" characters. Tomcat strips these out, but other containers may not. We should also strip these for matching.
        Hide
        Luke Taylor added a comment -

        A new strategy has been created (HttpFirewall) which is injected into the FilterChainProxy and wraps the requests prior to passing them down the filter chain. With the default implementation, the wrapper wil remove all path parameters from each segment of the URI while they are passing through the security filters. Sequences of multiple "/" characters are reduced to a single character. Unnormalized are rejected paths by default.

        If an alternative strategy is required, it can be injected directly into the FilterChainProxy bean or by using the http-firewall namespace element.

        Show
        Luke Taylor added a comment - A new strategy has been created (HttpFirewall) which is injected into the FilterChainProxy and wraps the requests prior to passing them down the filter chain. With the default implementation, the wrapper wil remove all path parameters from each segment of the URI while they are passing through the security filters. Sequences of multiple "/" characters are reduced to a single character. Unnormalized are rejected paths by default. If an alternative strategy is required, it can be injected directly into the FilterChainProxy bean or by using the http-firewall namespace element.

          People

          • Assignee:
            Luke Taylor
            Reporter:
            Luke Taylor
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: