mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-10-26 08:06:09 +01:00
Fix path traversal vulnerability
This commit is contained in:
committed by
René Pfeuffer
parent
0fe8914f9d
commit
1021640a4c
@@ -21,7 +21,7 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
package sonia.scm.plugin;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
@@ -38,37 +38,32 @@ import java.nio.file.Path;
|
||||
* @author Sebastian Sdorra
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class PathWebResourceLoader implements WebResourceLoader
|
||||
{
|
||||
public class PathWebResourceLoader implements WebResourceLoader {
|
||||
|
||||
private static final String SEPARATOR = "/";
|
||||
|
||||
private final Path directory;
|
||||
|
||||
/**
|
||||
* the logger for PathWebResourceLoader
|
||||
*/
|
||||
private static final Logger LOG =
|
||||
LoggerFactory.getLogger(PathWebResourceLoader.class);
|
||||
private static final Logger LOG = LoggerFactory.getLogger(PathWebResourceLoader.class);
|
||||
|
||||
public PathWebResourceLoader(Path directory)
|
||||
{
|
||||
this.directory = directory;
|
||||
public PathWebResourceLoader(Path directory) {
|
||||
this.directory = directory.toAbsolutePath().normalize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getResource(String path) {
|
||||
URL resource = null;
|
||||
Path file = directory.resolve(filePath(path));
|
||||
Path file = directory.resolve(filePath(path)).toAbsolutePath().normalize();
|
||||
|
||||
if (Files.exists(file) && ! Files.isDirectory(file))
|
||||
{
|
||||
if (isValidPath(file)) {
|
||||
LOG.trace("found path {} at {}", path, file);
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
resource = file.toUri().toURL();
|
||||
}
|
||||
catch (MalformedURLException ex)
|
||||
{
|
||||
} catch (MalformedURLException ex) {
|
||||
LOG.error("could not transform path to url", ex);
|
||||
}
|
||||
} else {
|
||||
@@ -78,6 +73,12 @@ public class PathWebResourceLoader implements WebResourceLoader
|
||||
return resource;
|
||||
}
|
||||
|
||||
private boolean isValidPath(Path file) {
|
||||
return Files.exists(file)
|
||||
&& !Files.isDirectory(file)
|
||||
&& file.startsWith(directory);
|
||||
}
|
||||
|
||||
private String filePath(String path) {
|
||||
if (path.startsWith(SEPARATOR)) {
|
||||
return path.substring(1);
|
||||
@@ -85,8 +86,4 @@ public class PathWebResourceLoader implements WebResourceLoader
|
||||
return path;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private final Path directory;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
package sonia.scm.plugin;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
@@ -42,11 +42,10 @@ import java.net.URL;
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class PathWebResourceLoaderTest extends WebResourceLoaderTestBase
|
||||
{
|
||||
public class PathWebResourceLoaderTest extends WebResourceLoaderTestBase {
|
||||
|
||||
@Test
|
||||
public void testGetNullForDirectories() throws IOException {
|
||||
public void shouldReturnNullForDirectories() throws IOException {
|
||||
File directory = temp.newFolder();
|
||||
assertTrue(new File(directory, "awesome").mkdir());
|
||||
|
||||
@@ -56,7 +55,7 @@ public class PathWebResourceLoaderTest extends WebResourceLoaderTestBase
|
||||
|
||||
|
||||
@Test
|
||||
public void testGetResource() throws IOException {
|
||||
public void shouldReturnResource() throws IOException {
|
||||
File directory = temp.newFolder();
|
||||
URL url = file(directory, "myresource").toURI().toURL();
|
||||
|
||||
@@ -68,4 +67,36 @@ public class PathWebResourceLoaderTest extends WebResourceLoaderTestBase
|
||||
assertNull(resourceLoader.getResource("other"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotReturnPathsWithAbsolutePath() throws IOException {
|
||||
File base = temp.newFolder();
|
||||
|
||||
File one = new File(base, "one");
|
||||
assertTrue(one.mkdirs());
|
||||
File two = new File(base, "two");
|
||||
assertTrue(two.mkdirs());
|
||||
|
||||
File secret = new File(two, "secret");
|
||||
assertTrue(secret.createNewFile());
|
||||
|
||||
WebResourceLoader resourceLoader = new PathWebResourceLoader(one.toPath());
|
||||
assertNull(resourceLoader.getResource(secret.getAbsolutePath()));
|
||||
assertNull(resourceLoader.getResource("/" + secret.getAbsolutePath()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotReturnPathsWithPathTraversal() throws IOException {
|
||||
File base = temp.newFolder();
|
||||
|
||||
File one = new File(base, "one");
|
||||
assertTrue(one.mkdirs());
|
||||
File two = new File(base, "two");
|
||||
assertTrue(two.mkdirs());
|
||||
|
||||
File secret = new File(two, "secret");
|
||||
assertTrue(secret.createNewFile());
|
||||
|
||||
WebResourceLoader resourceLoader = new PathWebResourceLoader(one.toPath());
|
||||
assertNull(resourceLoader.getResource("../two/secret"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user