ResourceHttpRequestHandler detects invalid directory traversal in given path (SPR-8515)
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -75,7 +75,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator implements H
|
|||||||
* for serving static resources.
|
* for serving static resources.
|
||||||
*/
|
*/
|
||||||
public void setLocations(List<Resource> locations) {
|
public void setLocations(List<Resource> locations) {
|
||||||
Assert.notEmpty(locations, "Location list must not be empty");
|
Assert.notEmpty(locations, "Locations list must not be empty");
|
||||||
this.locations = locations;
|
this.locations = locations;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +142,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator implements H
|
|||||||
HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE + "' is not set");
|
HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE + "' is not set");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!StringUtils.hasText(path) || path.contains("WEB-INF") || path.contains("META-INF")) {
|
if (!StringUtils.hasText(path) || isInvalidPath(path)) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Ignoring invalid resource path [" + path + "]");
|
logger.debug("Ignoring invalid resource path [" + path + "]");
|
||||||
}
|
}
|
||||||
@@ -172,6 +172,17 @@ public class ResourceHttpRequestHandler extends WebContentGenerator implements H
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the given path: returns {@code true} if the given path is not a valid resource path.
|
||||||
|
* <p>The default implementation rejects paths containing "WEB-INF" or "META-INF" as well as paths
|
||||||
|
* with relative paths ("../") that result in access of a parent directory.
|
||||||
|
* @param path the path to validate
|
||||||
|
* @return {@code true} if the path has been recognized as invalid, {@code false} otherwise
|
||||||
|
*/
|
||||||
|
protected boolean isInvalidPath(String path) {
|
||||||
|
return (path.contains("WEB-INF") || path.contains("META-INF") || StringUtils.cleanPath(path).startsWith(".."));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine an appropriate media type for the given resource.
|
* Determine an appropriate media type for the given resource.
|
||||||
* @param resource the resource to check
|
* @param resource the resource to check
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -20,7 +20,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@@ -32,6 +31,8 @@ import org.springframework.mock.web.MockServletContext;
|
|||||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||||
import org.springframework.web.servlet.HandlerMapping;
|
import org.springframework.web.servlet.HandlerMapping;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Keith Donald
|
* @author Keith Donald
|
||||||
* @author Jeremy Grelle
|
* @author Jeremy Grelle
|
||||||
@@ -119,6 +120,22 @@ public class ResourceHttpRequestHandlerTests {
|
|||||||
assertEquals("function foo() { console.log(\"hello world\"); }", response.getContentAsString());
|
assertEquals("function foo() { console.log(\"hello world\"); }", response.getContentAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getResourceViaDirectoryTraversal() throws Exception {
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.setMethod("GET");
|
||||||
|
|
||||||
|
request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "../testsecret/secret.txt");
|
||||||
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
|
handler.handleRequest(request, response);
|
||||||
|
assertEquals(404, response.getStatus());
|
||||||
|
|
||||||
|
request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "test/../../testsecret/secret.txt");
|
||||||
|
response = new MockHttpServletResponse();
|
||||||
|
handler.handleRequest(request, response);
|
||||||
|
assertEquals(404, response.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void notModified() throws Exception {
|
public void notModified() throws Exception {
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
|||||||
Reference in New Issue
Block a user