GeoServer arbitrary file upload vulnerability in REST Coverage Store API
Description
GeoServer is an open source software server written in Java that allows users to share and edit geospatial data. An arbitrary file upload vulnerability exists in versions prior to 2.23.4 and 2.24.1 that enables an authenticated administrator with permissions to modify coverage stores through the REST Coverage Store API to upload arbitrary file contents to arbitrary file locations which can lead to remote code execution. Coverage stores that are configured using relative paths use a GeoServer Resource implementation that has validation to prevent path traversal but coverage stores that are configured using absolute paths use a different Resource implementation that does not prevent path traversal. This vulnerability can lead to executing arbitrary code. An administrator with limited privileges could also potentially exploit this to overwrite GeoServer security files and obtain full administrator privileges. Versions 2.23.4 and 2.24.1 contain a fix for this issue.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.geoserver:gs-platformMaven | < 2.23.4 | 2.23.4 |
org.geoserver:gs-restconfigMaven | < 2.23.4 | 2.23.4 |
org.geoserver:gs-platformMaven | >= 2.24.0, < 2.24.1 | 2.24.1 |
org.geoserver:gs-restconfigMaven | >= 2.24.0, < 2.24.1 | 2.24.1 |
Affected products
1Patches
2ca683170c669[GEOS-11176] Add validation to file wrapper resource paths (#7233)
3 files changed · +44 −1
src/platform/src/main/java/org/geoserver/platform/resource/Files.java+21 −1 modified@@ -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; @@ -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()); @@ -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
src/platform/src/main/java/org/geoserver/platform/resource/URIs.java+1 −0 modified@@ -28,6 +28,7 @@ static class ResourceAdaptor implements Resource { private URL url; public ResourceAdaptor(URL url) { + Paths.valid(url.getPath()); this.url = url; }
src/platform/src/test/java/org/geoserver/platform/resource/ResourceTheoryTest.java+22 −0 modified@@ -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; @@ -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)); + } }
fe235b3bb1d7[GEOS-11176] Add validation to file wrapper resource paths (#7234)
3 files changed · +44 −1
src/platform/src/main/java/org/geoserver/platform/resource/Files.java+21 −1 modified@@ -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; @@ -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()); @@ -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
src/platform/src/main/java/org/geoserver/platform/resource/URIs.java+1 −0 modified@@ -28,6 +28,7 @@ static class ResourceAdaptor implements Resource { private URL url; public ResourceAdaptor(URL url) { + Paths.valid(url.getPath()); this.url = url; }
src/platform/src/test/java/org/geoserver/platform/resource/ResourceTheoryTest.java+22 −0 modified@@ -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; @@ -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)); + } }
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/advisories/GHSA-9v5q-2gwq-q9hqghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-51444ghsaADVISORY
- github.com/geoserver/geoserver/commit/ca683170c669718cb6ad4c79e01b0451065e13b8ghsax_refsource_MISCWEB
- github.com/geoserver/geoserver/commit/fe235b3bb1d7f05751a4a2ef5390c36f5c9e78aeghsax_refsource_MISCWEB
- github.com/geoserver/geoserver/pull/7222ghsax_refsource_MISCWEB
- github.com/geoserver/geoserver/security/advisories/GHSA-9v5q-2gwq-q9hqghsax_refsource_CONFIRMWEB
- osgeo-org.atlassian.net/browse/GEOS-11176ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.