/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2014 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.wms.map; import static org.junit.Assert.assertTrue; import java.awt.Color; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.logging.Level; import java.util.regex.Pattern; import org.geoserver.catalog.Catalog; import org.geoserver.catalog.StyleInfo; import org.geoserver.data.test.MockData; import org.geoserver.wms.GetMapRequest; import org.geoserver.wms.WMSMapContent; import org.geoserver.wms.WMSTestSupport; import org.geotools.data.FeatureSource; import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.map.FeatureLayer; import org.geotools.referencing.crs.DefaultGeographicCRS; import org.geotools.styling.Style; import org.geotools.util.logging.Logging; import org.junit.After; import org.junit.Before; import org.junit.Test; import com.vividsolutions.jts.geom.Envelope; public class OpenLayersMapOutputFormatTest extends WMSTestSupport { private OpenLayersMapOutputFormat mapProducer; Pattern lookForEscapedParam = Pattern .compile(Pattern .quote("\"</script><script>alert('x-scripted');</script><script>\": 'foo'")); @Before public void setMapProducer() throws Exception { Logging.getLogger("org.geotools.rendering").setLevel(Level.OFF); this.mapProducer = getProducerInstance(); } protected OpenLayersMapOutputFormat getProducerInstance() { return new OpenLayersMapOutputFormat(getWMS()); } @After public void unsetMapProducer() throws Exception { this.mapProducer = null; } /** * Test for GEOS-5318: xss vulnerability when a weird parameter is added to the * request (something like: %3C%2Fscript% * 3E%3Cscript%3Ealert%28%27x-scripted%27%29%3C%2Fscript%3E%3Cscript%3E=foo) the * causes js code execution. * * @throws IOException */ @Test public void testXssFix() throws Exception { Catalog catalog = getCatalog(); final FeatureSource fs = catalog.getFeatureTypeByName( MockData.BASIC_POLYGONS.getPrefix(), MockData.BASIC_POLYGONS.getLocalPart()) .getFeatureSource(null, null); final Envelope env = fs.getBounds(); LOGGER.info("about to create map ctx for BasicPolygons with bounds " + env); GetMapRequest request = createGetMapRequest(MockData.BASIC_POLYGONS); request.getRawKvp().put( "</script><script>alert('x-scripted');</script><script>", "foo"); final WMSMapContent map = new WMSMapContent(); map.getViewport().setBounds( new ReferencedEnvelope(env, DefaultGeographicCRS.WGS84)); map.setMapWidth(300); map.setMapHeight(300); map.setBgColor(Color.red); map.setTransparent(false); map.setRequest(request); StyleInfo styleByName = catalog.getStyleByName("Default"); Style basicStyle = styleByName.getStyle(); FeatureLayer layer = new FeatureLayer(fs, basicStyle); layer.setTitle("Title"); map.addLayer(layer); request.setFormat("application/openlayers"); RawMap rawMap = this.mapProducer.produceMap(map); ByteArrayOutputStream bos = new ByteArrayOutputStream(); rawMap.writeTo(bos); String htmlDoc = new String(bos.toByteArray(), "UTF-8"); // check that weird param is correctly encoded to avoid js code execution int index = htmlDoc .replace("\\n", "") .replace("\\r", "") .indexOf( "\"</script\\><script\\>alert(\\'x-scripted\\');</script\\><script\\>\": 'foo'"); assertTrue(index > -1); } }