cordovaphonegapcontent-security-policy

How to allow remote image src URLs in Apache Cordova app


I'm migrating create-react-app to Apache Cordova. My relative URLs to static images are working. Ex: ./images/path/to/file.jpeg

But in the iOS simulator I can't reference remote image sources in an S3 bucket. Ex: //s3-us-west-2.amazonaws.com/bla/bla/bla/8CCE-B64FD7247407.jpeg?1617374606

I think this is a security configuration issue, but I'm not sure. This is what is currently in my config.xml file:

    <access origin="*" allows-local-networking='true' />
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    <allow-intent href="*" />
    <platform name="android">
        <allow-intent href="market:*" />
    </platform>
    <platform name="ios">
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
        <allow-intent href="*" />
    </platform>

I currently have no <meta http-equiv="Content-Security-Policy" content="..."> in my index.html file.

What am I doing wrong?

Updates 1&2

I tried updating my config.xml file to include:

<allow-intent href="//:*/*" />
<access origin='*' allows-arbitrary-loads-for-media='true' allows-arbitrary-loads-in-web-content='true' allows-local-networking='true' />

Unfortunately this didn't work.

Like @DaveAlden suggested, it looks like this might be a CSP problem...

My original index.html file does not include the Content-Security-Policy meta tag at all, but when I run the cordova app in the browser and view the source. This is what I see:

<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">

Now I think my question is: Where is that CSP coming from? And, how do I modify it?

For a moment I was scratching my head as to why remote images are working in the browser because my understanding is that img-src 'self' should disallow <img src="//:bla-bla.amazonaws.com/bla/bla" />. I think part of the explanation is that when I use the dev tools to inspect the <head> of the document, I see a different CSP tag than when I view source. enter image description here 👆This CSP matches what I currently have in my index.html file before running cordova run ....

It seems like somehow Cordova is using a different, default CSP for iOS but somehow overriding it in the browser. I'm confused.

** Update 3**

I searched the files of my project and I discovered that the mysterious CSP (that I'm seeing in the browser) matches the default "template" policy listed on the cordova-plugin-whitelist README. <-- This suggests to me that my src index.html isn't getting used at all, and Cordova is falling back to an internal default.


Solution

  • Rrrrrrrr... I discovered that I can debug the iOS simulator using Safari and the CSP looks correct! I double-checked this in Safari and Chrome and they both show the correct CSP as well. So it appears that Firefox is showing something confusing when I click "View source" (I still can't explain this part) but this was a distraction from the real issue...

    iOS is trying to request the remote image file with an incorrect file:// prefix. I think this is connected to the fact that the AWS URLs don't specify the protocol. Ex: //s3-us-west-2.amazonaws.com/bla/bla/...

    The browsers seem to handle this just fine. But in the iOS simulator, it seems to think it's a local file. Notice that it has a file:// prefix.

    I changed the API to return https:// and now it works in the simulator.

    enter image description here