Skip to content

Commit

Permalink
[GEOS-11176] Add validation to file wrapper resource paths (#7234)
Browse files Browse the repository at this point in the history
Co-authored-by: Steve Ikeoka <steve.ikeoka@gdit.com>
  • Loading branch information
aaime and sikeoka committed Oct 30, 2023
1 parent 53ae090 commit fe235b3
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 1 deletion.
Expand Up @@ -14,6 +14,7 @@
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
Expand Down Expand Up @@ -47,9 +48,28 @@ static final class ResourceAdaptor implements Resource {
final File file;

private ResourceAdaptor(File file) {
valid(file.getPath());
this.file = file.getAbsoluteFile();
}

/**
* GeoServer unit tests heavily utilize single period path components (e.g., ./something or
* target/./something) and Windows path separators when running on Windows so this method is
* a more lenient version of {@link Paths#valid(String)} that only checks for double period
* path components to prevent path traversal vulnerabilities.
*
* @param path the file path
* @return the file path
* @throws IllegalArgumentException If path contains '..'
*/
private static String valid(String path) {
if (path != null
&& Arrays.stream(Paths.convert(path).split("/")).anyMatch(".."::equals)) {
throw new IllegalArgumentException("Contains invalid '..' path: " + path);
}
return path;
}

@Override
public String path() {
return Paths.convert(file.getPath());
Expand Down Expand Up @@ -199,7 +219,7 @@ public Resource parent() {

@Override
public Resource get(String resourcePath) {
return new ResourceAdaptor(new File(file, resourcePath));
return new ResourceAdaptor(new File(file, valid(resourcePath)));
}

@Override
Expand Down
Expand Up @@ -28,6 +28,7 @@ static class ResourceAdaptor implements Resource {
private URL url;

public ResourceAdaptor(URL url) {
Paths.valid(url.getPath());
this.url = url;
}

Expand Down
Expand Up @@ -32,7 +32,9 @@
import java.util.Collection;
import java.util.List;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.SystemUtils;
import org.geoserver.platform.resource.Resource.Type;
import org.junit.Test;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;
Expand Down Expand Up @@ -490,4 +492,24 @@ public void theoryRootIsAbsolute(String path) throws Exception {
final Resource res = getResource(Paths.convert(file.getPath()));
assertTrue(Paths.isAbsolute(res.path()));
}

@Test
public void testPathTraversal() {
assertInvalidPath("..");
assertInvalidPath("../foo/bar");
assertInvalidPath("foo/../bar");
assertInvalidPath("foo/bar/..");
}

@Test
public void testPathTraversalWindows() {
assumeTrue(SystemUtils.IS_OS_WINDOWS);
assertInvalidPath("..\\foo\\bar");
assertInvalidPath("foo\\..\\bar");
assertInvalidPath("foo\\bar\\..");
}

protected final void assertInvalidPath(String path) {
assertThrows(IllegalArgumentException.class, () -> getResource(path));
}
}

0 comments on commit fe235b3

Please sign in to comment.