Search code examples
javascriptcordovabase64cordova-pluginscontent-security-policy

Cordova won't fetch anything base64, no matter what's in the CSP


I'm using Cordova's camera plugin to allow my app to take photos, and so far just cannot get it to do anything with the returned data.

I've given up on trying to load it from the filesystem URL, and am now trying with base64.

My CSP is:

<meta http-equiv="Content-Security-Policy" content="
    default-src *; 
    style-src * 'unsafe-inline'; 
    script-src * 'unsafe-inline' 'unsafe-eval'; 
    media-src *; 
    img-src * data:; 
    connect-src * ws: wss:;
" />

...however I've tried every other CSP I can find on the internet. No matter what's in there, my console always logs:

"Refused to connect to 'data:image/jpg;base64... because it violates the document's Content Security Policy.", source: http://localhost:8080/js/main.js"

Does anyone know why this is the case, or how I'd go about fixing it?

The code to turn the image data into a file is:

navigator.camera.getPicture(response => {
    this.urltoFile('data:image/jpg;base64,'+response, 'test.jpg')
        .then(file => {
            console.log(file);
        })
    }, () => {}, {
    destinationType : navigator.camera.DestinationType.DATA_URL,
})

...and the urlToFile function is:

urltoFile(url, filename){
    let mimeType = (url.match(/^data:([^;]+);/)||'')[1];

    return (fetch(url)
        .then(res => {
            return res.arrayBuffer();
        })
        .then(buf => {
            return new File([buf], filename, { 
                type: mimeType 
            });
        })
    );
}

Solution

  • As per your code you are using the Fetch API to download pictures as base64.

    Looking at the docs, the Fetch API is restricted by the connect-src directive (emphasis is mine):

    The HTTP Content-Security-Policy (CSP) connect-src directive restricts the URLs which can be loaded using script interfaces. The APIs that are restricted are:

    • <a> ping,
    • Fetch,
    • XMLHttpRequest,
    • WebSocket, and
    • EventSource.

    So we'll have to alter your connect-src to accept data Urls by adding data: to the directive like so:

    connect-src * data: ws: wss:;