[SPR-8515] ResourceHttpRequestHandler should check for directory traversal Created: 06/Jul/11 Updated: 19/Jun/12 Resolved: 22/Jul/11 Status: Project: Component/s: Affects Version/s: Fix Version/s: Closed Spring Framework Web 3.0.4, 3.0.5 Type: Reporter: Resolution: Labels: Remaining Estimate: Time Spent: Original Estimate: Improvement Johannes Scharf Complete None Not Specified 3.0.6, 3.1 RC1 Priority: Assignee: Votes: Minor Rossen Stoyanchev 0 Not Specified Not Specified 4 years, 29 weeks, 2 days ago Days since last comment: Last commented false by a User: Trevor Marshall Last updater: Description The ResourceHttpRequestHandler which was introduced in Spring 3.0.4 (see ) and supersedes ResourceServlet from Spring WebFlow doesn't check for directory traversal. Given the following configuration it is possible to traverse one hierachy up and get access to resources which may not should be exposed to the outside. Example: Given the application runs under /myapp and the DispatcherServlet is mapped onto path /main/* and the configuration of the ResourceHttpRequestHandler is as follows: <mvc:resources location="/META-INF/public-web-resources/" mapping="/resources/**" /> With a tool like "Burp Proxy" it is now possible to issue a request like that: GET /myapp/main/resources/../secret-web-resources/secret.txt HTTP/1.1 This would traverse up to path /META-INF/secret-web-resources and expose "secret.txt". A more fatal configuration would be <mvc:resources location="/WEB-INF/public-web-resources/" mapping="/resources/**" /> which would allow for an attacker to expose "web.xml" with a request like GET /myapp/main/resources/../web.xml HTTP/1.1 The deeper the mapping of ResourceHttpRequestHandler is, the higher the path can be traversed. A mapping like <mvc:resources location="/WEB-INF/public-web-resources/" mapping="/resources/css/**" /> would even allow for traversing two directories up. That is because the request URI seems to be resolved by Tomcat before it tries find a matching servlet mapping. Later on the original path - containing ".." - gets passed to the servlet. So it is possible that the resulting URI doesn't match the Spring DispatcherServlet mapping any more. This seems to be a kind of barrier for the directory traversal attack. Also classpath resources (eg. classpath:/dir/) can be exposed that way. The tests were performed with Tomcat 6.0.29 under Windows XP SP 3. Summary: ResourceHttpRequestHandler doesn't check for directory traversal Thus resources either in web context or classpath with a known media type can be exposed The deeper the mapping of the ResourceHttpRequestHandler is, the higher the path can be traversed In my book, the ResourceServlet from Spring WebFlow follows a much more secure approach by matching the path against some patterns to check if it is allowed. Suggestions: The ResourceHttpRequestHandler should check if the resolved Resource is beneath the given location and NOT above of it. Following that approach the attacker would be jailed into the (parent) location. From a user's perspective it would be much more intuitive if only resources beneath a given location are exposed to the outside. Comments Comment by Rossen Stoyanchev [ 20/Jul/11 ] Using Tomcat 6, I send this URL: /mvc-showcase/resources/../forbidden/forbidden.css By the time the request reaches the DispatcherServlet the URL is normalized and results in a 404: /mvc-showcase/forbidden/forbidden.css So I am not able to reproduce the issue. ResourceHttpRequestHandler has specific checks for whether the path contains WEB-INF or META-INF (line 145). Such requests are ignored. Do you actually see the behavior you described? Comment by Johannes Scharf [ 20/Jul/11 ] How do you send the URL? With a browser? That doesn't work. I saw the same behavior as you described with Firefox. I'm pretty sure the problem exists as I have tested it multiple times with different URLs. Checks for "WEB-INF" only prevent against URLs with such a part in it - but that's not always the case. See my examples above. Comment by Rossen Stoyanchev [ 22/Jul/11 ] Okay, so it's Firefox that normalized the URL. I see the issue now. The ResourceHttpRequestHandler only checks for "WEB-INF" and "META-INF" in the path within the handler mapping. If the resource handler is already mapped to a location under /META-INF (or under /WEB-INF) the URL does not have contain "METAINF" or "WEB-INF" in order to use the traversing you showed. In any case traversing outside the root of the mapped directory is not in the intent of the mapping. Comment by Johannes Scharf [ 24/Jul/11 ] There won't be a fix for 3.0.x? Comment by Juergen Hoeller [ 25/Jul/11 ] Backported to 3.0.6 now. Juergen Generated at Wed Feb 10 05:07:04 UTC 2016 using JIRA 6.4.11#64026sha1:78f6ec473a3f058bd5d6c30e9319c7ab376bdb9c.