Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSP directives prevents map from loading #4062

Closed
felixLam opened this issue Jan 28, 2017 · 14 comments
Closed

CSP directives prevents map from loading #4062

felixLam opened this issue Jan 28, 2017 · 14 comments

Comments

@felixLam
Copy link

felixLam commented Jan 28, 2017

Adding the CSP directive in the meta tag as described in https://github.com/mapbox/mapbox-gl-js/blob/master/INSTALL.md#using-mapbox-with-csp does not work as expected and leads to the map not loading correctly.

Minimal example https://mapbox-csp-bug.myshopify.com/pages/mapbox-csp-bug

The map displays correctly in Chrome, but fails to load with an error on Safari (Version 10.0.2 (12602.3.12.0.1).

This precludes usage of map box gl on any shopify hosted website (and other hosts where the developer for whatever reason cannot or does not want to change the CSP header).

Original issue:
#3982 (comment)

@jfirebaugh
Copy link
Contributor

Here's what I see in the console when loading the codepen in Safari:

[Error] Refused to load http://production-assets.codepen.io/assets/common/stopExecutionOnTimeout-58d22c749295bca52f487966e382a94a495ac103faca9206cbd160bdf8aedf2a.js because it does not appear in the script-src directive of the Content Security Policy.
[Error] Refused to load http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js because it does not appear in the script-src directive of the Content Security Policy.
[Error] Refused to execute a script because its hash, its nonce, or 'unsafe-inline' does not appear in the script-src directive of the Content Security Policy. (index.html, line 23)

So the security policy is preventing codepen from working at all. Can you set up an example that doesn't depend on codepen?

@jfirebaugh
Copy link
Contributor

Your example also won't work due to the inline script, and the fact that it's missing child-src blob:. The following works in Safari for me:

<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://* blob: data:; script-src https://* 'sha256-NwPGqa9Mxa7ZIeBSPi4K97Vtt3uBWjwtJsUlZfeqG5E' 'unsafe-eval'; style-src 'unsafe-inline' https://*; child-src blob: ; connect-src https://*;">
<link rel="stylesheet" href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.8.1/mapbox-gl.css">
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v0.8.1/mapbox-gl.js"></script>
<style>
    * {
        box-sizing: border-box;
    }
    body {
        margin: 0;
        padding: 0;
    }

    #map {
        position: absolute;
        top: 0;
        bottom: 0;
        width: 100%;
    }
</style>
<div id='map'></div>
<script>
    mapboxgl.accessToken = 'pk.eyJ1IjoiZmFsbGVuYXJ0aXN0IiwiYSI6IkRHY2JKRWMifQ.m6rylJF-IEcmwtiRsVO1WA';

    var center = [51.5, -0.1];

    var map = new mapboxgl.Map({
        container: 'map',
        center: center,
        zoom: 8,
        style: 'https://www.mapbox.com/mapbox-gl-styles/styles/mapbox-streets-v7.json'
    });
</script>

@felixLam
Copy link
Author

felixLam commented Jan 28, 2017

Hi @jfirebaugh Thanks for your snippet and sorry for my late night coding mistake with the code pen sample. I have setup a dev store on shopify that includes a minimal html page including the meta tag above:
https://mapbox-csp-bug.myshopify.com/pages/mapbox-csp-bug

In the process I also found why it does not work on shopify but appears to do fine on a vanilla server. The reason is that web workers do not follow the CSP of the document, but rather of the request that served it:

Workers are considered to have their own execution context, distinct from the document that created them. For this reasons they are, in general, not governed by the content security policy of the document (or parent worker) that created them. [...]
To specify a content security policy for the worker, set a Content-Security-Policy response header for the request which delivered the worker script itself.
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#Content_security_policy

The mapbox js sdk is served without this header. My assumption is that Safari then falls back to the document's request header which ignores any changes to the meta tag for the workers.

To reproduce locally setup a server and set the following headers (as used by shopify):

add_header Content-Security-Policy "default-src 'self' https://*; connect-src 'self' https://* wss://*; font-src 'self' https://* blob: data:; frame-src 'self' https://* blob: data:; img-src 'self' https://* blob: data:; media-src 'self' https://* blob: data:; object-src 'self' https://* blob: data:; script-src 'self' https://* 'unsafe-inline' 'unsafe-eval'; style-src 'self' https://* 'unsafe-inline';";

@felixLam
Copy link
Author

Related #559

@felixLam
Copy link
Author

felixLam commented Jan 30, 2017

I do not believe that this issue is limited to Shopify and would assume that other users experience similar issues. Nevertheless I also brought this up at Shopify: https://ecommerce.shopify.com/c/shopify-apis-and-technology/t/content-security-policy-response-headers-401287

@jfirebaugh
Copy link
Contributor

The source for the worker script isn't https://api.tiles.mapbox.com/mapbox-gl-js/v0.8.1/mapbox-gl.js, it's a blob: URL that is generated at runtime. According to https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy#CSP_in_workers:

The exception to this is if the worker script's origin is a globally unique identifier (for example, if its URL has a scheme of data or blob). In this case, the worker does inherit the content security policy of the document or worker than created it.

Therefore the worker script should be allowed in this scenario, since both the meta tag and the response header include child-src blob:. It looks like a Safari bug to me.

@jfirebaugh
Copy link
Contributor

jfirebaugh commented Jan 30, 2017

Actually, it looks like a Shopify bug. They appear to be returning different CSP headers depending on the browser.

Chrome -- child-src present:

Content-Security-Policy: default-src 'self' https://*; child-src 'self' https://* blob: data:; connect-src 'self' https://* wss://*; font-src 'self' https://* blob: data:; img-src 'self' https://* blob: data:; media-src 'self' https://* blob: data:; object-src 'self' https://* blob: data:; script-src 'self' https://* 'unsafe-inline' 'unsafe-eval'; style-src 'self' https://* 'unsafe-inline'; report-uri /csp-report?source%5Baction%5D=pages&source%5Bapp%5D=Shopify&source%5Bcontroller%5D=storefront_section%2Fshop&source%5Bsection%5D=storefront&source%5Buuid%5D=7cbe81cf-46cc-4028-b139-210f67ccff28

Safari -- child-src missing:

Content-Security-Policy: default-src 'self' https://*; connect-src 'self' https://* wss://*; font-src 'self' https://* blob: data:; frame-src 'self' https://* blob: data:; img-src 'self' https://* blob: data:; media-src 'self' https://* blob: data:; object-src 'self' https://* blob: data:; script-src 'self' https://* 'unsafe-inline' 'unsafe-eval'; style-src 'self' https://* 'unsafe-inline'; report-uri /csp-report?source%5Baction%5D=pages&source%5Bapp%5D=Shopify&source%5Bcontroller%5D=storefront_section%2Fshop&source%5Bsection%5D=storefront&source%5Buuid%5D=5b1533f9-bdf6-4cd8-8329-cca8ed0b222a

@jfirebaugh
Copy link
Contributor

Closing since this is an issue with Shopify's browser sniffing.

@thomaskimura
Copy link

Running into the same issue on Shopify. Can't find a solution for this

@pearsonhenri
Copy link

Was running into this and fixed it by adding the following CSP directive to my server:

worker-src 'self' blob:;

@yipcma
Copy link

yipcma commented Aug 10, 2017

it is most strange. child-src blob:; works for cordova ios, but not worker-src blob:;

@jonnybarnes
Copy link

@nordurljosahvida
Copy link

@jonnybarnes Does this also affect iframes? I'm embedding via iframe as shown here but i keep getting:

Content Security Policy: Directive ‘child-src’ has been deprecated. Please use directive ‘worker-src’ to control workers, or directive ‘frame-src’ to control frames respectively.

Thanks

@eldang
Copy link

eldang commented Dec 15, 2021

I ran into this with an added twist which may be helpful for others: I've found that if I'm hosting a Mapbox map in a subdomain, I also need to set a CSP of "worker-src 'self' blob:;" for the site root, because Mapbox tries to launch workers which appear to hosted at blob:https://DOMAINNAME/RANDOMSTRING even when it's running in a subdirectory.

All the other includes can be arranged at just the subdirectory level, but that one has to be at the root.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants