Format HttpFirewall Reference

Put each sentence on a newline.

Issue: gh-5022
This commit is contained in:
Rob Winch 2018-02-15 17:16:52 -06:00
parent 0fc67f765a
commit 6f48afbfe6
1 changed files with 31 additions and 5 deletions

View File

@ -3377,20 +3377,46 @@ The order that filters are defined in the chain is very important. Irrespective
[[request-matching]] [[request-matching]]
=== Request Matching and HttpFirewall === Request Matching and HttpFirewall
Spring Security has several areas where patterns you have defined are tested against incoming requests in order to decide how the request should be handled. This occurs when the `FilterChainProxy` decides which filter chain a request should be passed through and also when the `FilterSecurityInterceptor` decides which security constraints apply to a request. It's important to understand what the mechanism is and what URL value is used when testing against the patterns that you define. Spring Security has several areas where patterns you have defined are tested against incoming requests in order to decide how the request should be handled.
This occurs when the `FilterChainProxy` decides which filter chain a request should be passed through and also when the `FilterSecurityInterceptor` decides which security constraints apply to a request.
It's important to understand what the mechanism is and what URL value is used when testing against the patterns that you define.
The Servlet Specification defines several properties for the `HttpServletRequest` which are accessible via getter methods, and which we might want to match against. These are the `contextPath`, `servletPath`, `pathInfo` and `queryString`. Spring Security is only interested in securing paths within the application, so the `contextPath` is ignored. Unfortunately, the servlet spec does not define exactly what the values of `servletPath` and `pathInfo` will contain for a particular request URI. For example, each path segment of a URL may contain parameters, as defined in http://www.ietf.org/rfc/rfc2396.txt[RFC 2396] footnote:[You have probably seen this when a browser doesn't support cookies and the `jsessionid` parameter is appended to the URL after a semi-colon. However the RFC allows the presence of these parameters in any path segment of the URL]. The Specification does not clearly state whether these should be included in the `servletPath` and `pathInfo` values and the behaviour varies between different servlet containers. There is a danger that when an application is deployed in a container which does not strip path parameters from these values, an attacker could add them to the requested URL in order to cause a pattern match to succeed or fail unexpectedly. footnote:[The original values will be returned once the request leaves the `FilterChainProxy`, so will still be available to the application.]. Other variations in the incoming URL are also possible. For example, it could contain path-traversal sequences (like `/../`) or multiple forward slashes (`//`) which could also cause pattern-matches to fail. Some containers normalize these out before performing the servlet mapping, but others don't. To protect against issues like these, `FilterChainProxy` uses an `HttpFirewall` strategy to check and wrap the request. Un-normalized requests are automatically rejected by default, and path parameters and duplicate slashes are removed for matching purposes. footnote:[So, for example, an original request path `/secure;hack=1/somefile.html;hack=2` will be returned as `/secure/somefile.html`.]. It is therefore essential that a `FilterChainProxy` is used to manage the security filter chain. Note that the `servletPath` and `pathInfo` values are decoded by the container, so your application should not have any valid paths which contain semi-colons, as these parts will be removed for matching purposes. The Servlet Specification defines several properties for the `HttpServletRequest` which are accessible via getter methods, and which we might want to match against.
These are the `contextPath`, `servletPath`, `pathInfo` and `queryString`.
Spring Security is only interested in securing paths within the application, so the `contextPath` is ignored.
Unfortunately, the servlet spec does not define exactly what the values of `servletPath` and `pathInfo` will contain for a particular request URI.
For example, each path segment of a URL may contain parameters, as defined in http://www.ietf.org/rfc/rfc2396.txt[RFC 2396]
footnote:[You have probably seen this when a browser doesn't support cookies and the `jsessionid` parameter is appended to the URL after a semi-colon.
However the RFC allows the presence of these parameters in any path segment of the URL].
The Specification does not clearly state whether these should be included in the `servletPath` and `pathInfo` values and the behaviour varies between different servlet containers.
There is a danger that when an application is deployed in a container which does not strip path parameters from these values, an attacker could add them to the requested URL in order to cause a pattern match to succeed or fail unexpectedly.
footnote:[The original values will be returned once the request leaves the `FilterChainProxy`, so will still be available to the application.].
Other variations in the incoming URL are also possible.
For example, it could contain path-traversal sequences (like `/../`) or multiple forward slashes (`//`) which could also cause pattern-matches to fail.
Some containers normalize these out before performing the servlet mapping, but others don't.
To protect against issues like these, `FilterChainProxy` uses an `HttpFirewall` strategy to check and wrap the request.
Un-normalized requests are automatically rejected by default, and path parameters and duplicate slashes are removed for matching purposes.
footnote:[So, for example, an original request path `/secure;hack=1/somefile.html;hack=2` will be returned as `/secure/somefile.html`.].
It is therefore essential that a `FilterChainProxy` is used to manage the security filter chain.
Note that the `servletPath` and `pathInfo` values are decoded by the container, so your application should not have any valid paths which contain semi-colons, as these parts will be removed for matching purposes.
As mentioned above, the default strategy is to use Ant-style paths for matching and this is likely to be the best choice for most users. The strategy is implemented in the class `AntPathRequestMatcher` which uses Spring's `AntPathMatcher` to perform a case-insensitive match of the pattern against the concatenated `servletPath` and `pathInfo`, ignoring the `queryString`. As mentioned above, the default strategy is to use Ant-style paths for matching and this is likely to be the best choice for most users.
The strategy is implemented in the class `AntPathRequestMatcher` which uses Spring's `AntPathMatcher` to perform a case-insensitive match of the pattern against the concatenated `servletPath` and `pathInfo`, ignoring the `queryString`.
If for some reason, you need a more powerful matching strategy, you can use regular expressions. The strategy implementation is then `RegexRequestMatcher`. See the Javadoc for this class for more information. If for some reason, you need a more powerful matching strategy, you can use regular expressions.
The strategy implementation is then `RegexRequestMatcher`.
See the Javadoc for this class for more information.
In practice we recommend that you use method security at your service layer, to control access to your application, and do not rely entirely on the use of security constraints defined at the web-application level. URLs change and it is difficult to take account of all the possible URLs that an application might support and how requests might be manipulated. You should try and restrict yourself to using a few simple ant paths which are simple to understand. Always try to use a "deny-by-default" approach where you have a catch-all wildcard ( /** or **) defined last and denying access. In practice we recommend that you use method security at your service layer, to control access to your application, and do not rely entirely on the use of security constraints defined at the web-application level.
URLs change and it is difficult to take account of all the possible URLs that an application might support and how requests might be manipulated.
You should try and restrict yourself to using a few simple ant paths which are simple to understand.
Always try to use a "deny-by-default" approach where you have a catch-all wildcard ( /** or **) defined last and denying access.
Security defined at the service layer is much more robust and harder to bypass, so you should always take advantage of Spring Security's method security options. Security defined at the service layer is much more robust and harder to bypass, so you should always take advantage of Spring Security's method security options.
The `HttpFirewall` also prevents https://www.owasp.org/index.php/HTTP_Response_Splitting[HTTP Response Splitting] by rejecting new line characters in the HTTP Response headers. The `HttpFirewall` also prevents https://www.owasp.org/index.php/HTTP_Response_Splitting[HTTP Response Splitting] by rejecting new line characters in the HTTP Response headers.
=== Use with other Filter-Based Frameworks === Use with other Filter-Based Frameworks
If you're using some other framework that is also filter-based, then you need to make sure that the Spring Security filters come first. This enables the `SecurityContextHolder` to be populated in time for use by the other filters. Examples are the use of SiteMesh to decorate your web pages or a web framework like Wicket which uses a filter to handle its requests. If you're using some other framework that is also filter-based, then you need to make sure that the Spring Security filters come first. This enables the `SecurityContextHolder` to be populated in time for use by the other filters. Examples are the use of SiteMesh to decorate your web pages or a web framework like Wicket which uses a filter to handle its requests.