Sunday, 5 December 2021

Safari and Chrome-Mobile (iOS) blocks execution of Scripts from "blob:" src in sandboxed iframe

I have an website that embeds a user-defined page using an iframe with the sandbox-Attribute set to allow-scripts.

The embedded website is also itself hosted by me (it's coming from the same origin server), but it includes potentially unsafe Javascript. I don't want to add the allow-same-origin value to the sandbox Attribute, because this would defat the whole purpose.

The embedded page has the Content-Security-Policy Header set like this:

Content-Security-Policy: style-src 'self' https://example.com/webjars/ https://example.com/css/ 'unsafe-inline' blob:; script-src 'self' https://example.com/webjars/ https://example.com/js/ 'unsafe-eval' 'unsafe-inline' blob:; default-src 'none'; navigate-to 'none'

where example.com is my domain.

The embedded page tries to dynamically add Javascript/CSS using the following code:

    const createScriptElement = function(js) {
        const element = document.createElement("script")
        element.type = "text/javascript"

        if (Blob && URL && URL.createObjectURL) {
            element.src = URL.createObjectURL(new Blob([js], {"type": "text/javascript"}))
        } else {
            element.innerHTML = js
        }

        return element
    }

    const createStyleElement = function(css) {
        let element

        if (Blob && URL && URL.createObjectURL) {
            element = document.createElement("link")
            element.rel = "stylesheet"
            element.type = "text/css"
            element.href = URL.createObjectURL(new Blob([css], {"type": "text/css"}))
        } else {
            element = document.createElement("style")
            element.innerHTML = css
        }

        return element
    }

This should be allowed and it works fine on Chrome (Desktop/Windows+MacOS).

However, on Chrome Mobile (iOS) and Safari (MacOS, iOS) it rejects to execute both the Javascript and the CSS. On the console, the following message pops up:

[blocked] The page at https://example.com/embedded_page_url was not allowed to run insecure content from blob:null/<uuid>.

I can see that the Content-Security-Policy value for script-src and style-src contains blob: (as you can see above).

When I manually "disable" the URL.createObjectURL in the embedded page using URL.createObjectURL = null it works fine (because, as you can see in the js-code above, the creation of the dynamic script/style elements has a fallback to inline the code if URL.createObjectURL is not supported).

Is there anything I'm missing? I would prefer to use the blob: URLs to embed this type of content if the feature is available instead of always inlining the dynamic scripts.



from Safari and Chrome-Mobile (iOS) blocks execution of Scripts from "blob:" src in sandboxed iframe

No comments:

Post a Comment