Stricter CSP compatibility for WebGL worker
We use OpenLayers in an application with fairly strict security. As part of that the use of CSP worker-src blob: is not permitted^1.
However OpenLayers loads the WebGL worker from a blob that's created from a const source = "entire worker script here";. As far as I understand, this is to ensure that you can load OpenLayers from a single script tag without any external dependencies.
As a workaround we currently have an NPM post install hook that uses regex matching to extract the contents of the source literal from webgl.js into a file in our public assets folder, and rewrite webgls.js create function to:
return new Worker(new URL('assets/openlayers-webgl-worker.js'), document.baseURIThis works but it's kind of ugly. I wonder whether it's possible to create a solution that supports both use cases.
Options I can think of are:
- Store web worker code in a file instead of (or in addition to) a literal, let the developer pass an URL to use at runtime to load that file from where it's published.
- Replace the worker loader code with something that dynamically adds a script tag to the page. Publish the hash of the source so CSP users can add that hash to their CSP. Simple but library updates get the additional gotcha that users must (sometimes) update their CSP on deployment.
- Replace the worker loader code with something that dynamically adds a script tag to the page. Allow the developer to inject a CSP nonce. This is how our application handles this for other workers such as those of code-mirror. It works very nicely, but involves a more complex set-up. We let the server that publishes the CSP to auto-generate and inject a nonce in the main index HTML.
4.2.2.1. Security Considerations for GUID URL schemes
… allowing "blob:" or "filesystem:" URLs is equivalent to unsafe-eval.
Source: openlayers/openlayers