CSP headers and custom projections

When I use the MapML extension’s custom projection support with CSP headers enabled, I can’t load a preview of a layer because of this error:

“Refused to execute inline script because it violates the following Content Security Policy directive: “script-src ‘self’”. Either the ‘unsafe-inline’ keyword, a hash (‘sha256-2sJUkPb9cvIywDZasBuNbfeR8To3fjZRZX00mzIX1xQ=’), or a nonce (‘nonce-…’) is required to enable inline execution.”

The HTML document contains a <script type="module"> containing the projection definition inline, and this is disallowed by the CSP. I am wondering if there is a way to either generate the hash and add it to the HTML script tag or preferably to enable the projection definition as a web resource that could be fetched via <script src="URL to projection definition script" type=module>.

I note that individual CRS definitions are available for viewing in the admin interface, but I am not aware of any way to fetch them as a resource from GeoServer. e.g.

http://localhost:8080/geoserver/web/wicket/bookmarkable/org.geoserver.web.demo.SRSDescriptionPage?42&code=MapML:EPSG3573

Any thoughts appreciated!

Peter

Could make a REST API end-point for the CRS definitions. It could be added as part of the MapML module, or to core (as it would be general purpose).

1 Like

In the spirit of consistency, is there another similar end point that could be used as a model for such a REST API? I see that CRS definitions come out of GeoTools, and accessing them is not like a traditional GeoServer REST API as such. I imagine it would be a read-only API. Maybe the styles end point would be the correct model or at least provide something to go by.

Hi all,

REST API endpoint as in “geoserver/rest” are by default locked down to admin only usage, it would not work for this case (opening it up requires changing the rest security property file, which might already have been customized.

Getting a nonce is supported by GeoServerApplication.getNonce(), but that requires having the wicket UI in the classpath, something we cannot assume to be there in general…

On the other hand, it’s not easy to have a new WMS request just to grab a Javascript snippet (which is dynamically generated). @sikeoka did you prepare some support for these cases?

Hum… thiniking out loud, would it be possible to rework the MapML custom CRS support to use a static javascript along with a hidden input field that only contains the proj definition? I believe the OpenLayers previews were reworked like that, e.g., they have a lot of hidden fields acting as parameters:

    <input type="hidden" id="pureCoverage" value="false"/>
    <input type="hidden" id="supportsFiltering" value="true"/>
    <input type="hidden" id="minX" value="145.19754"/>
    <input type="hidden" id="minY" value="-43.423512"/>
    <input type="hidden" id="maxX" value="148.27298000000002"/>
    <input type="hidden" id="maxY" value="-40.852802"/>
    <input type="hidden" id="SRS" value="EPSG:4326"/>
    <input type="hidden" id="yx" value="true"/>
    <input type="hidden" id="global" value="true"/>
    <input type="hidden" id="baseUrl" value="https://gs-main.geosolutionsgroup.com/geoserver"/>
    <input type="hidden" id="servicePath" value="ogcapi/wms"/>
    <input type="hidden" id="units" value="degrees"/>
    <input type="hidden" class="param" title="STYLES" value=""/>
    <input type="hidden" class="param" title="LAYERS" value="ogcapi:tasmania_no_roads"/>
    <input type="hidden" class="param" title="EXCEPTIONS" value="application/vnd.ogc.se_inimage"/>

and then some static JS file fetching from them, e.g.:

  var projectionParams = {
    code: document.getElementById('SRS').value,
    units: document.getElementById('units').value,
    global: document.getElementById('global').value == 'true'
  };

Regards,
Andrea Aime

I would like to be able to refer to the custom projection definition without having it be parameterized across the html + static script. The webresources/wms path looks interesting as a target, although it sounds from the name like it contains static resources, while having a dynamic custom projection script module generated there would be more useful (I think), as it could be linked to from within the HTML preview:

<script src="http://localhost:8080/geoserver/webresources/wms/MapML%3ACUSTOMTCRS" integrity="calculate a hash"></script>

but also I think it might be useful if it was linked to from within the actual MapML document as well, because it would make the MapML document useful by non-preview clients that didn’t already know about the projection definition, perhaps something like this:

<map-link rel="projection" href="http://localhost:8080/geoserver/webresources/wms/MapML%3ACUSTOMTCRS"></map-link>

of course I would have to update the MapML.js library to use such a link but just thinking out loud. We do have the concept of <map-input type="hidden"> in MapML, so a parameterized approach might also work, so not rejecting but have to think about it.

Can you test this PR? [GEOS-11719] MapML custom projections blocked by content security policy by sikeoka · Pull Request #8320 · geoserver/geoserver · GitHub