VYPR
Moderate severityNVD Advisory· Published Mar 20, 2024· Updated Aug 1, 2024

GeoServer Stored Cross-Site Scripting (XSS) vulnerability in Simple SVG Renderer

CVE-2024-23642

Description

GeoServer is an open source software server written in Java that allows users to share and edit geospatial data. A stored cross-site scripting (XSS) vulnerability exists in versions prior to 2.23.4 and 2.24.1 that enables an authenticated administrator with workspace-level privileges to store a JavaScript payload in the GeoServer catalog that will execute in the context of another user's browser when viewed in the WMS GetMap SVG Output Format when the Simple SVG renderer is enabled. Access to the WMS SVG Format is available to all users by default although data and service security may limit users' ability to trigger the XSS. Versions 2.23.4 and 2.24.1 contain a fix for this issue.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.geoserver:gs-wmsMaven
< 2.23.42.23.4
org.geoserver:gs-wmsMaven
>= 2.24.0, < 2.24.12.24.1

Affected products

1

Patches

2
1b1835afbb9c

[GEOS-11152] Improve handling special characters in the Simple SVG Renderer (#7299)

https://github.com/geoserver/geoserverSteve IkeokaNov 28, 2023via ghsa
2 files changed · +49 38
  • src/wms/src/main/java/org/geoserver/wms/svg/StreamingSVGMap.java+4 2 modified
    @@ -5,6 +5,8 @@
      */
     package org.geoserver.wms.svg;
     
    +import static org.apache.commons.text.StringEscapeUtils.escapeXml10;
    +
     import java.io.IOException;
     import java.io.OutputStream;
     import java.util.List;
    @@ -138,10 +140,10 @@ private void writeLayers() throws IOException {
     
                     String styleName = layer.getStyle().getName();
     
    -                writer.write("<g id=\"" + groupId + "\"");
    +                writer.write("<g id=\"" + escapeXml10(groupId) + "\"");
     
                     if (!styleName.startsWith("#")) {
    -                    writer.write(" class=\"" + styleName + "\"");
    +                    writer.write(" class=\"" + escapeXml10(styleName) + "\"");
                     }
     
                     writer.write(">\n");
    
  • src/wms/src/test/java/org/geoserver/wms/svg/SVGMapProducerTest.java+45 36 modified
    @@ -6,11 +6,7 @@
     package org.geoserver.wms.svg;
     
     import java.awt.Color;
    -import java.io.ByteArrayInputStream;
     import java.io.ByteArrayOutputStream;
    -import java.io.StringReader;
    -import javax.xml.parsers.DocumentBuilder;
    -import javax.xml.parsers.DocumentBuilderFactory;
     import org.custommonkey.xmlunit.XMLAssert;
     import org.custommonkey.xmlunit.XMLUnit;
     import org.geoserver.wms.WMSMapContent;
    @@ -31,13 +27,31 @@
     import org.locationtech.jts.geom.Polygon;
     import org.opengis.feature.simple.SimpleFeature;
     import org.opengis.feature.simple.SimpleFeatureType;
    -import org.w3c.dom.Document;
    -import org.xml.sax.InputSource;
     
     public class SVGMapProducerTest extends WMSTestSupport {
     
    -    @Test
    -    public void testHeterogeneousGeometry() throws Exception {
    +    private static String EXPECTED_DOC =
    +            "<?xml version=\"1.0\" standalone=\"no\"?>"
    +                    + "<svg xmlns=\"http://www.w3.org/2000/svg\""
    +                    + "    xmlns:xlink=\"http://www.w3.org/1999/xlink\""
    +                    + "    stroke=\"green\""
    +                    + "    fill=\"none\""
    +                    + "    stroke-width=\"0.1%\""
    +                    + "    stroke-linecap=\"round\""
    +                    + "    stroke-linejoin=\"round\""
    +                    + "    width=\"300\""
    +                    + "    height=\"300\""
    +                    + "    viewBox=\"-250.0 -250.0 500.0 500.0\""
    +                    + "    preserveAspectRatio=\"xMidYMid meet\">"
    +                    + "  <g id=\"LAYER\" class=\"STYLE\">"
    +                    + "    <use x=\"10\" y=\"-10\" xlink:href=\"#point\"/>"
    +                    + "    <path d=\"M50 -50l50 -50 \"/>"
    +                    + "    <path d=\"M0 0l0 -200 200 0 0 200 -200 0 Z\"/>"
    +                    + "  </g>"
    +                    + "</svg>";
    +
    +    private void doTestSVGMapProducer(String layer, String style, String expectedDoc)
    +            throws Exception {
             GeometryFactory gf = new GeometryFactory();
             Point point = gf.createPoint(new Coordinate(10, 10));
             LineString line =
    @@ -56,7 +70,7 @@ public void testHeterogeneousGeometry() throws Exception {
                             null);
     
             SimpleFeatureTypeBuilder ftb = new SimpleFeatureTypeBuilder();
    -        ftb.setName("test");
    +        ftb.setName(layer);
             ftb.add("geom", Geometry.class);
             SimpleFeatureType type = ftb.buildFeatureType();
     
    @@ -68,7 +82,7 @@ public void testHeterogeneousGeometry() throws Exception {
             ds.createSchema(type);
             ds.addFeatures(f1, f2, f3);
     
    -        FeatureSource fs = ds.getFeatureSource("test");
    +        FeatureSource fs = ds.getFeatureSource(layer);
     
             final WMSMapContent map = new WMSMapContent();
             map.getViewport().setBounds(new ReferencedEnvelope(-250, 250, -250, 250, null));
    @@ -78,6 +92,7 @@ public void testHeterogeneousGeometry() throws Exception {
             map.setTransparent(false);
     
             Style basicStyle = getCatalog().getStyleByName("Default").getStyle();
    +        basicStyle.setName(style);
             map.addLayer(new FeatureLayer(fs, basicStyle));
     
             SVGStreamingMapOutputFormat producer = new SVGStreamingMapOutputFormat();
    @@ -86,33 +101,27 @@ public void testHeterogeneousGeometry() throws Exception {
             encodeSVG.encode(out);
             // System.out.println(out.toString());
     
    -        String expectedDoc =
    -                "<?xml version=\"1.0\" standalone=\"no\"?>"
    -                        + "<svg xmlns=\"http://www.w3.org/2000/svg\" " //
    -                        + "    xmlns:xlink=\"http://www.w3.org/1999/xlink\" " //
    -                        + "    stroke=\"green\"  " //
    -                        + "    fill=\"none\"  " //
    -                        + "    stroke-width=\"0.1%\" " //
    -                        + "    stroke-linecap=\"round\" " //
    -                        + "    stroke-linejoin=\"round\" " //
    -                        + "    width=\"300\"  " //
    -                        + "    height=\"300\"  " //
    -                        + "    viewBox=\"-250.0 -250.0 500.0 500.0\"  " //
    -                        + "    preserveAspectRatio=\"xMidYMid meet\"> " //
    -                        + "  <g id=\"test\" class=\"Default\"> " //
    -                        + "    <use x=\"10\" y=\"-10\" xlink:href=\"#point\"/> " //
    -                        + "    <path d=\"M50 -50l50 -50 \"/> " //
    -                        + "    <path d=\"M0 0l0 -200 200 0 0 200 -200 0 Z\"/> " //
    -                        + "  </g> " //
    -                        + "</svg> ";
    -
    -        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    -        Document expected = builder.parse(new InputSource(new StringReader(expectedDoc)));
    -        Document result = builder.parse(new ByteArrayInputStream(out.toByteArray()));
    -
             XMLUnit.setIgnoreWhitespace(true);
             XMLUnit.setIgnoreAttributeOrder(true);
    -        XMLUnit.setIgnoreComments(true);
    -        XMLAssert.assertXMLEqual(expected, result);
    +        XMLAssert.assertXMLEqual(expectedDoc, out.toString());
    +    }
    +
    +    @Test
    +    public void testHeterogeneousGeometry() throws Exception {
    +        String layer = "test";
    +        String style = "Default";
    +        String expectedDoc = EXPECTED_DOC.replace("LAYER", layer).replace("STYLE", style);
    +        doTestSVGMapProducer(layer, style, expectedDoc);
    +    }
    +
    +    @Test
    +    public void testEscaping() throws Exception {
    +        String unescapedLayer = "layer\"<>";
    +        String escapedLayer = "layer&quot;&lt;&gt;";
    +        String unescapedStyle = "style\"<>";
    +        String escapedStyle = "style&quot;&lt;&gt;";
    +        String expectedDoc =
    +                EXPECTED_DOC.replace("LAYER", escapedLayer).replace("STYLE", escapedStyle);
    +        doTestSVGMapProducer(unescapedLayer, unescapedStyle, expectedDoc);
         }
     }
    
9f40265febb5

[GEOS-11152] Improve handling special characters in the Simple SVG Renderer

https://github.com/geoserver/geoserverSteve IkeokaOct 10, 2023via ghsa
2 files changed · +49 38
  • src/wms/src/main/java/org/geoserver/wms/svg/StreamingSVGMap.java+4 2 modified
    @@ -5,6 +5,8 @@
      */
     package org.geoserver.wms.svg;
     
    +import static org.apache.commons.text.StringEscapeUtils.escapeXml10;
    +
     import java.io.IOException;
     import java.io.OutputStream;
     import java.util.List;
    @@ -138,10 +140,10 @@ private void writeLayers() throws IOException {
     
                     String styleName = layer.getStyle().getName();
     
    -                writer.write("<g id=\"" + groupId + "\"");
    +                writer.write("<g id=\"" + escapeXml10(groupId) + "\"");
     
                     if (!styleName.startsWith("#")) {
    -                    writer.write(" class=\"" + styleName + "\"");
    +                    writer.write(" class=\"" + escapeXml10(styleName) + "\"");
                     }
     
                     writer.write(">\n");
    
  • src/wms/src/test/java/org/geoserver/wms/svg/SVGMapProducerTest.java+45 36 modified
    @@ -6,11 +6,7 @@
     package org.geoserver.wms.svg;
     
     import java.awt.Color;
    -import java.io.ByteArrayInputStream;
     import java.io.ByteArrayOutputStream;
    -import java.io.StringReader;
    -import javax.xml.parsers.DocumentBuilder;
    -import javax.xml.parsers.DocumentBuilderFactory;
     import org.custommonkey.xmlunit.XMLAssert;
     import org.custommonkey.xmlunit.XMLUnit;
     import org.geoserver.wms.WMSMapContent;
    @@ -31,13 +27,31 @@
     import org.locationtech.jts.geom.LineString;
     import org.locationtech.jts.geom.Point;
     import org.locationtech.jts.geom.Polygon;
    -import org.w3c.dom.Document;
    -import org.xml.sax.InputSource;
     
     public class SVGMapProducerTest extends WMSTestSupport {
     
    -    @Test
    -    public void testHeterogeneousGeometry() throws Exception {
    +    private static String EXPECTED_DOC =
    +            "<?xml version=\"1.0\" standalone=\"no\"?>"
    +                    + "<svg xmlns=\"http://www.w3.org/2000/svg\""
    +                    + "    xmlns:xlink=\"http://www.w3.org/1999/xlink\""
    +                    + "    stroke=\"green\""
    +                    + "    fill=\"none\""
    +                    + "    stroke-width=\"0.1%\""
    +                    + "    stroke-linecap=\"round\""
    +                    + "    stroke-linejoin=\"round\""
    +                    + "    width=\"300\""
    +                    + "    height=\"300\""
    +                    + "    viewBox=\"-250.0 -250.0 500.0 500.0\""
    +                    + "    preserveAspectRatio=\"xMidYMid meet\">"
    +                    + "  <g id=\"LAYER\" class=\"STYLE\">"
    +                    + "    <use x=\"10\" y=\"-10\" xlink:href=\"#point\"/>"
    +                    + "    <path d=\"M50 -50l50 -50 \"/>"
    +                    + "    <path d=\"M0 0l0 -200 200 0 0 200 -200 0 Z\"/>"
    +                    + "  </g>"
    +                    + "</svg>";
    +
    +    private void doTestSVGMapProducer(String layer, String style, String expectedDoc)
    +            throws Exception {
             GeometryFactory gf = new GeometryFactory();
             Point point = gf.createPoint(new Coordinate(10, 10));
             LineString line =
    @@ -56,7 +70,7 @@ public void testHeterogeneousGeometry() throws Exception {
                             null);
     
             SimpleFeatureTypeBuilder ftb = new SimpleFeatureTypeBuilder();
    -        ftb.setName("test");
    +        ftb.setName(layer);
             ftb.add("geom", Geometry.class);
             SimpleFeatureType type = ftb.buildFeatureType();
     
    @@ -68,7 +82,7 @@ public void testHeterogeneousGeometry() throws Exception {
             ds.createSchema(type);
             ds.addFeatures(f1, f2, f3);
     
    -        FeatureSource fs = ds.getFeatureSource("test");
    +        FeatureSource fs = ds.getFeatureSource(layer);
     
             final WMSMapContent map = new WMSMapContent();
             map.getViewport().setBounds(new ReferencedEnvelope(-250, 250, -250, 250, null));
    @@ -78,6 +92,7 @@ public void testHeterogeneousGeometry() throws Exception {
             map.setTransparent(false);
     
             Style basicStyle = getCatalog().getStyleByName("Default").getStyle();
    +        basicStyle.setName(style);
             map.addLayer(new FeatureLayer(fs, basicStyle));
     
             SVGStreamingMapOutputFormat producer = new SVGStreamingMapOutputFormat();
    @@ -86,33 +101,27 @@ public void testHeterogeneousGeometry() throws Exception {
             encodeSVG.encode(out);
             // System.out.println(out.toString());
     
    -        String expectedDoc =
    -                "<?xml version=\"1.0\" standalone=\"no\"?>"
    -                        + "<svg xmlns=\"http://www.w3.org/2000/svg\" " //
    -                        + "    xmlns:xlink=\"http://www.w3.org/1999/xlink\" " //
    -                        + "    stroke=\"green\"  " //
    -                        + "    fill=\"none\"  " //
    -                        + "    stroke-width=\"0.1%\" " //
    -                        + "    stroke-linecap=\"round\" " //
    -                        + "    stroke-linejoin=\"round\" " //
    -                        + "    width=\"300\"  " //
    -                        + "    height=\"300\"  " //
    -                        + "    viewBox=\"-250.0 -250.0 500.0 500.0\"  " //
    -                        + "    preserveAspectRatio=\"xMidYMid meet\"> " //
    -                        + "  <g id=\"test\" class=\"Default\"> " //
    -                        + "    <use x=\"10\" y=\"-10\" xlink:href=\"#point\"/> " //
    -                        + "    <path d=\"M50 -50l50 -50 \"/> " //
    -                        + "    <path d=\"M0 0l0 -200 200 0 0 200 -200 0 Z\"/> " //
    -                        + "  </g> " //
    -                        + "</svg> ";
    -
    -        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    -        Document expected = builder.parse(new InputSource(new StringReader(expectedDoc)));
    -        Document result = builder.parse(new ByteArrayInputStream(out.toByteArray()));
    -
             XMLUnit.setIgnoreWhitespace(true);
             XMLUnit.setIgnoreAttributeOrder(true);
    -        XMLUnit.setIgnoreComments(true);
    -        XMLAssert.assertXMLEqual(expected, result);
    +        XMLAssert.assertXMLEqual(expectedDoc, out.toString());
    +    }
    +
    +    @Test
    +    public void testHeterogeneousGeometry() throws Exception {
    +        String layer = "test";
    +        String style = "Default";
    +        String expectedDoc = EXPECTED_DOC.replace("LAYER", layer).replace("STYLE", style);
    +        doTestSVGMapProducer(layer, style, expectedDoc);
    +    }
    +
    +    @Test
    +    public void testEscaping() throws Exception {
    +        String unescapedLayer = "layer\"<>";
    +        String escapedLayer = "layer&quot;&lt;&gt;";
    +        String unescapedStyle = "style\"<>";
    +        String escapedStyle = "style&quot;&lt;&gt;";
    +        String expectedDoc =
    +                EXPECTED_DOC.replace("LAYER", escapedLayer).replace("STYLE", escapedStyle);
    +        doTestSVGMapProducer(unescapedLayer, unescapedStyle, expectedDoc);
         }
     }
    

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

News mentions

0

No linked articles in our index yet.