Whitelist External Resources For Use In Ionic Framework

It was recently brought to my attention that big things came with the latest Apache Cordova Android and iOS update.  One of the major updates being the requirement of whitelisting in order to use external resources.

What exactly does this mean?

Take the example of some random API like Facebook or TinyURL.  If you try to perform a request on either of these APIs it will fail because by default everything external is blacklisted.  By adding to the whitelist, things change.

We’re going to continue on the TinyURL example.  We’re going to create a simple application using Ionic Framework that will take a long URL and shrink it.

Let’s start by creating a fresh Android and iOS Ionic Framework project using the Terminal (Mac and Linux) or Command Prompt (Windows):

Note, if you’re not using a Mac, you cannot add and build for the iOS platform.

Open your project’s www/js/app.js file and add the following controller:

In the above code you’ll notice it is quite simple.  Just make a request to TinyURL and show an alert with the response.  The response being the short URL.

Let’s create a simple UI to go with this controller.  Open your project’s www/index.html file and add the following code, replacing the <ion-content> tags:

Nothing too complicated so far.

Build and run this project for Android by doing the following:

Wait a second!  I thought this was an article regarding whitelisting?  Well, run what we’ve done so far and you’ll see what I’m talking about.  You should get an error with a message like this in your logs:

Ionic Framework Blacklist TinyURL

That’s not good!  So how do we fix this?

Install the latest Apache Cordova Whitelist Plugin like the following:

Per the official documentation you should also add a Content Security Policy to prevent Android from complaining, although it isn’t required in all scenarios.  To allow everything, add the following to your www/index.html file right below the other meta tags:

When you build and run now, you shouldn’t have any problems.

Conclusion

In the latest Apache Cordova 4.0.0 Android and iOS release you’re required to whitelist any external resources that you want to use.  By default everything is blacklisted.  In this example we saw how to use the TinyURL API to get short URL versions.  This whitelisting concept also applies to the previous Facebook API example that I wrote and published on GitHub.

A video version of this article can be seen below.

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.

  • Thank you Nic, I had same issue, and used whitelist plugin to fix it.

    • Yep, everyone is suffering from this Apache Cordova change recently. You’re not alone 🙂

      • Yes, I have another issue, I use build.phonegap.com to build apps, but I can not find Whitelist plugin there.

        Thank you for replay.

        • I forwarded your inquiry about PhoneGap Build to my friend at Adobe.

          • Thank you very much, there are many plugins don’t appear there.

          • Nicolas Grolleau

            In phonegap build, you should use npm for plugin provided by the cordova team or the http://plugins.cordova.io/ repository for most plugins.

            I think plugins from phonegap build’s repository are mostly no more updated because you have to be a paying subscriber to submit a plugin.

            To use a plugin from repositories, add the source parameter to the gap:plugin line. :

            For more detailed info, please read the phonegap build documentation : http://docs.build.phonegap.com/en_US/configuring_plugins.md.html

          • Thanks, will try with npm.

          • Thanks for sharing this information!

  • Are you sure the default is to blacklist everything? I made a virgin Cordova project and added Android. It added the whitelist plugin automatically and added access origin * to my config.xml.

    • Hmpth, you are right. I coulda sworn I read that the access tag would work for backwards compat.

      • Yea it is killing everyone. The correct XML exists in the config file, but it gets ignored without the plugin. One of the commenters is saying that PhoneGap Build is missing it which I imagine is a critical issue for Adobe.

        I’ve seen this issue cause troubles with my Oauth library and RESTful API calls. All around bad news if you don’t know about the whitelist change.

      • Trying to parse the value used by CSP and it is insanely weird. I’m surprised the official docs don’t provide more guidance. Given this string, which is the default:

        “default-src ‘self’ data: gap: https://ssl.gstatic.com ‘unsafe-eval’; style-src ‘self’ ‘unsafe-inline’; media-src *”

        How do we read this? Do we split it by semi colons? If so we have this:

        default-src ‘self’ data: gap: https://ssl.gstatic.com ‘unsafe-eval’;
        style-src ‘self’ ‘unsafe-inline’;
        media-src *”

        So what is default-src in this context?
        What is style-src? I guess it is the rule for tags use rel=stylesheets – but what do “self” and “unsafe-line” imply?

        Given the above, it seems like the rule is:

        item 1 is the scope (style sheet, media, etc) and everything after is flags.

        • Yea I don’t think this change was too well thought out by the Apache Foundation. It needed to be done, but it shouldn’t have come without all the appropriate documentation. Very confusing.

      • Wow, still fighting just to get this line working:
        Which usually I’d just host locally – but I want to figure this out.

        • Report back anything you find 🙂

          • I got it working – given I wanted to load jquery and do an XHR to cnn, I did this:

            script-src ‘self’ http://code.jquery.com; connect-src http://www.cnn.com

            I’m not sure what the self keyword does – I assume it means localhost. Need to read more.

        • So this is what got me in the whitelist plugin. I was going to post on this last week, but when i read this, I decided not to:

          “However, the default Cordova application includes <access origin="*"> by default.”

          I read that as, “Yes, the access tag is old school, but we’re still adding it so your old stuff works.”

          To be fair, I blame me for not reading carefully enough. I think this part later on:

          “On Android, support for CSP within the system webview starts with KitKat (but is available on all versions using Crosswalk WebView).”

          Makes it obvious.

          OH! I think I know what got me. One minute…

        • Boom. Now I know why I got confused. I have my own Cordova skeleton app that I use because I do not like the default Cordova one. If you do NOT use the meta tag, you do NOT get the ‘new’ protection. So with that, AND me seeing the access tag, AND me perhaps reading the docs a bit too quickly, I thought an “out of the box” virgin app didn’t need this. Now it is making sense. Nic, do you mind if I post on this as well, point folks to your blog, and share some of the issues I ran into?

          • Definitely dude! Go spread some knowledge 🙂

  • hi Nic,
    i just had the same issue, and i found out the solution by chance, it is very hard to read and find the error in the logcat 1000 lines, so i found about the whitelist plugin (via google) and i installed it, but i did not add the Content-Security-Policy to the meta, i did add the url that i want to acess his api to the config.xml:
    <allow-navigation href=”http://myurl.com/api />

    and it works too.
    Regards

  • So a tip. default-src is a default for *-src, but when you specify a specific item, like script-src, it does NOT do a merge. So if you do script-src and do NOT include ‘self’, you will lose the ability to load local scripts, including cordova.js.

  • Anil Kumar

    Hi Nic,
    It is generating the tiny url but it is show as the server as not found with error number 404

    Thanks & Regards
    Anil Kumar B

    • Mind sharing your full error logs in the comments?

      • Anil Kumar

        Hi Nic,
        can you find the attached document please, after doing the tinyUrl app I am unable to run other projects and it is showing the error which is attached in the screenshot.
        Note: The server is Up and I checked through ping and I executed my code in other systems also

        Regards
        Anil Kumar B

        • A few things:

          Don’t use Ionic Serve if you have plugins in your project. It has limited compatibility, just like Ionic View.
          You have errors beyond the 404 errors

          My best recommendation is for you to build and install your application rather than trying to serve it or using a build service.

          Regards,

  • Rodrigo Graça

    Hi!

    This is why my Imgur.com image was not loading 😉

    Just a note, you always use “ionic build …” and then “adb …”, you can use “ionic run” and it will build it and send it to the emulator or device. 🙂

    Thanks!

    • “ionic run” has a history of problems so I decided to drop it. Best thing you can do is a build then an install.

      Regards,

      • Rodrigo Graça

        What problems? Could you elaborate?
        I’ve been using it every day….

        • I found it to have issues with cleanup, so often the build will be mangled on install. It creates a headache when trying to troubleshoot if it is your code with the problems or just a messed up build.

          Use “ionic run” as you’d like, but just know I’m not the only person having these problems.

          • Rodrigo Graça

            Thanks for elaborating.
            I will keep using it, if at any point I notice any problem I will let you know 🙂

      • adalberto Joco

        I had problems with it, now I do like you, build and adb install.

  • sameera207

    Hi Nic,

    Great post as always :),

    I had an issue with displaying a blank screen in my very basic app. They when I didn some googling , I landed on this thread (http://forum.ionicframework.com/t/showing-blank-white-screen/15545/19), I followed the steps but still my app shows a blank screen

    Please read my original question here (http://forum.ionicframework.com/t/ionic-view-shows-blank-screen-but-works-in-emulator/25405) (sorry for all the links, dont want to clutter this page with all the content)

    Any help will be much appreciated

    Thanks in advance

    cheers

    sam

    • Your links appear to be unrelated to my article. To keep comments useful for future readers, please direct unrelated questions at my Twitter or find an article that I’ve made where it would be relevant.

      Regards,

      • sameera207

        Hi Nic,

        Sorry for the late reply. Since my app calls the external API, I was under the impression that this latest Cordova change was casing the issue.

        But turns out that, it was about not loading ngCordova correctly.

        So apologies if I made things confusing 🙂

        cheers

  • NicoH

    Hi nic,

    Your help served me well in several problems I had, however, he brought other. All my connections work well at different sites and web services, but load google maps does not work with the “” header.

    • What do your error logs say?

      • zqudlyba

        Yeah. I got the same problem with Angular Maps as NicoH. With Cordova 5, the meta Content-Security-Policy described above doesn’t work. I get this error: Refused to load the stylesheet ‘https://fonts.googleapis.com/css?family=Roboto:300,400,500,700’ because it violates the following Content Security Policy directive: “style-src ‘self’ ‘unsafe-inline’ “. I get the same error on a real Android device, desktop chrome, and IonicView. I even tried desktop chrome with –disable-web-security but same error. I tried millions of combinations of but meta Content-Security-Policy none worked. This meta is supposedly the most permissive but Cordova 5 doesn’t like it when it comes to Ionic + Angular Google Maps:

        • Pak

          Same problem here. Were you able to solve it ?

        • I can’t recommend hooking your app to remote resources like that. It will cause a mess of problems if the user is not online.

          You should download the font files and include them in your application.

          Regards,

  • Hey Nic,
    I am having “ERROR: null” thrown when running on livereload and on a device, but not in the simulator on a regular emulator. That may not be an uncommon problem, as evidenced by the comment thread.

    If you have any suggestions, I will gladly take them.

    Thank you!

    • I encourage you to not use live-reload. Your best bet for app development is to build a binary and install it to the device. Example:

      Regards,

      • How would I do this on iOS? I am getting the error from using Xcode.

        • Do:

          Then open your project in Xcode and run from there.

          • I figured it out;: it was actual the iOS 9 setting regarding resource sharing.

          • I haven’t touched iOS 9 yet. I have no idea its compatibility with Apache Cordova at the moment.

  • grumpyOldCat

    I love your tutorials, dude… every time pretty straight forward!

  • Santino Wu

    Hi, Nic!

    I followed your tutorial to setup the whitelist plugin and add a meta into index.html, however, my app didn’t load the data which from my local server(e.g. http://localhost:8000/api…) and it worked fine in the ios simulator, did i miss something to setup?

    Thank you!

    • The Android simulator and devices cannot communicate on localhost. You’ll need to figure out the correct IP address or host your web application so it can be accessed via a domain name.

      Regards,

      • Santino Wu

        Thank you, i reinstalled whitelist plugin and re-build android and then it worked fine.

        Best

  • therealjamesg

    As soon as I add the meta tag, everything breaks: http://puu.sh/klgj7/0b7292dd44.png

    • That error usually means you have a typo in your code. Do you have a stray semi colon or character that shouldn’t be there? I’ve gotten that error 100s of times and it has all been due to typos.

      • therealjamesg

        Nope. Like I said, take the meta tag out and everything works, add it back and it all breaks. If it were a typo, the top line would be something like “unexpected token” or “”expected ) after argument list” or similar

        • Not true. That error can also relate to typos. Yes it doesn’t make sense on why it would, but it does.

          I assure you that line works as I use it in all my applications.

          Why don’t you post your full project on GitHub and I’ll see if I can spot your problem.

          Regards,

          • therealjamesg

            It’s already in bitbucket but it’s marked private for now.

          • If you want further help I’m going to need to see your full project. I know this works as I use it myself. The reason for your error may not be what I think it is, but more often than not, it is what I think it is.

            Regards,

          • therealjamesg

            I would love to get this sorted out. Can we hook up on Twitter and so we can DM contact details? I can then share the project to you without having to show my frankly embarrassing code to everyone (it will come, it’s just not ready yet!)

            I’m @slashwhatever

          • Sorry, but I don’t do private messaging or distribute my contact information. I’d be happy to help you, but you’ll have to go by my rules.

            If you’d rather not share your code, why don’t you pass your project through three linters, HTML, JavaScript, CSS and see if you have any problems. It won’t catch everything, but it is a start.

            Sorry,

          • therealjamesg

            Fair enough. I can guarantee it’s not a code error though. It works without the meta tag and whitelist plugin and has done for weeks. While waiting I even took them back out – flawless again.

            I’ll just live without ionic deploy.

          • Ah, I didn’t hear the whole story!

            I have never had any success with any of the Ionic products (deploy, view, serve). Best bet is to build and distribute them yourself.

            Regards,

          • therealjamesg

            Well, the end goal is to use ionic deploy but without the whitelist working, that’s obviously not going to happen. For now, this is it working without the meta tag, breaking with it in place and then working without it again: http://recordit.co/Myx4lZEM69

  • Paresh Gami

    i am this thing but in my samsung mobile it is working but in my mi phone it is not working it is always goes in error part of http call. please help me. Thanks

  • Rajeshwar Reddy

    When i add

    in index.html file, I am getting the following errors:

    (index):1 Refused to load the script ‘https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places’ because it violates the following Content Security Policy directive: “script-src ‘self’ ‘unsafe-inline’ ‘unsafe-eval'”.

    (index):134 Refused to load the script ‘http://localhost:35729/livereload.js?snipver=1’ because it violates the following Content Security Policy directive: “script-src ‘self’ ‘unsafe-inline’ ‘unsafe-eval'”.

    • Are you using ionic serve, ionic view, or ionic live reload?

      • Rajeshwar Reddy

        I am using “ionic run ios –device -lc”. I am getting the same error when i was using “ionic serve” also.

        • Looks like you’re using live-reload. I also didn’t realize that this is failing in iOS. Are you using Xcode 7 or iOS 9?

          • Rajeshwar Reddy

            Yes, i am using both of them.

          • Can you post this to Ionic’s issue tracker? Xcode 7 and iOS 9 have a ton of problems with Ionic Framework, but this seems like a larger problem as that meta line is often required for Android. If making it work on Android makes it fail on iOS, this would be a bad thing.

            Best,

          • Rajeshwar Reddy

            Thanks for your replies.

          • Carlos Levano

            Any solution an this?… I have the same problem , do not load the map GoogleMaps in my app that is already in distribution in the store AppStore, Android works great , but never ends IOS load the map.

  • John B Dougherty

    Using the suggested “allow everything” meta tag

    using

    ionic build android
    adb install -r platforms/android/build/outputs/apk/android-debug.apk

    totally breaks my app for my newsreader

    and without the meta tag I get this error in Meteor if I have the newsreader app running on the android while I’m playing with a Meteor demo:

    I20151011-14:34:07.561(-7) (android:file:///android_asset/www/plugins/cordova-plugin-console/www/console-via-logger.js:173) No Content-Security-Policy meta tag found. Please add one when using the cordova-plugin-whitelist plugin.

    • When you say it breaks everything, what do your logs say?

      • John B Dougherty

        guessing that I would be using adb logcat? how would I filter that output?
        Basically the select box is populated by a php callback that provides id, title, and link for the various feeds it lists. Without that nothing else can work – and I don’t get that with the”allow everything” meta tag.

        • Yes you would need to use adb logcat. It is impossible for me to help you without seeing logs. Too many possibilities.

          Regards,

          • John B Dougherty

            it’s all good Nic – I am not even sure this thing should be an app – just a responsive site would be fine – was just test driving ionic- this seems to be a cordova issue – like the right hand doesn’t know what the left hand is doing.

          • There are many moving parts in Apache Cordova applications. Anything is possible 🙂

          • John B Dougherty

            here’s a couple dumps – weird that the one with my newsreader running is smaller.

            454178 Oct 15 05:34 svr_rss-off
            448305 Oct 15 05:35 svr_rss-on

            https://dl.dropboxusercontent.com/u/58227690/nrayboy/svr_rss-off

            https://dl.dropboxusercontent.com/u/58227690/nrayboy/svr_rss-on

          • John B Dougherty

            hey Nick – I just followed through your

            Create an RSS Reader Using AngularJS and IonicFramework tutorial

            and discovered the inappbrowser version I had been using from

            https://www.npmjs.com/package/cordova-plugin-inappbrowser

            is not at all the same as the one you use from

            https://git-wip-us.apache.org/repos/asf/cordova-plugin-inappbrowser.git

            apache.org version loads your blog in chrome, I don’t know what the npmjs.com version loads, but as far as any of my previous questions – I have to sort out my apples from my oranges!

          • Yea, it is tough for me to keep up with all the name changes. The correct InAppBrowser tag to use as of now is:

            cordova plugin add cordova-plugin-inappbrowser

            In a perfect world, Apache will keep all their tags in sync.

            Best,

  • kkai316

    Hello Nic,

    I really enjoy your ionic tutorial. I came across a problem that I am stuck for few days. I am trying to get json data from an api (it’s “https://…” ) and I have installed whitelist plugin. I am able to see on web browser(ionic serve) but when I emulate on device is not showing(ionic run ios). Is it something different I need to deal with http and https api? Thanks!

    • Rule #1, don’t use ionic serve, ionic view, ionic live-reload, or phonegap build to test your applications. These tools are all beta or alpha and will never give you a true experience.

      After you build and install to a device, let me know what your logs say and we’ll go from there.

      Best,

      • kkai316

        Thanks for your advice. I enable developer option on my andriod phone “ionic build android” first then do “ionic run android”. It will run on my device. Then I can see my json data! Does that count as install to my device? I was trying to install Android SDK and set it up on my computer(Mac) for emulate but still not working for now…

        • The way you installed it to your device looks correct. Is it successful?

          If you’re having issues with the SDK you may want to post to the forums.

          Best,

          • kkai316

            Yeah, it runs successfully. I will keep researching on set up SDK. Thank you so much!

          • No problem!

  • Camilo Lopes

    good post. But in my case my app is not working. any idea? I have added whitelist cordova and crosswalk ionicc: http://blog.ionic.io/crosswalk-comes-to-ionic/ but without success.

    • Did you add the meta tag?

      • Camilo Lopes

        Yes Nic. I added meta tag :

        • Maybe the plugin got corrupted on install? It happens sometimes.

          The meta tag seems correct, and the error is obviously whitelist related. Also check your config.xml file and make sure you don’t have any overrides in there in terms of whitelisting.

          Regards,

  • If you’re using -livereload and getting errors when including .js files from localhost, add http://localhost:*/ to script-src.

    • Thanks for pointing this out 🙂

  • Lorenzo

    Hello Nik, and thanks for the post. I was wondering if to enable everything like that could give security issues for the application. I’ve just tryed to delete the ‘unsafe-inline’ and ‘unsafe-eval’ for the script and css, but it looks like ionic really needs these settings.
    Thanks in advanced for support.

    • You’re right! You probably don’t want to open the door to all and possibly unsafe resources. You should definitely trim it down and only whitelist what you need. However, for the sake of the example, I figured it might be alright to just set people in the right direction.

      Thanks for your feedback 🙂

      • Lorenzo

        Yes, I am agree. But using ionic, from what I am seeing, ‘unsafe-inline’ and ‘unsafe-eval’ have to be active. So, about Content Policy settings, what we can do is only to set the domain from where the app can make ajax request.
        By the way, I know I am out of topic, but I didn’t find on your blog the right article to post the question.
        I am trying to understand a way to make my API gives data only from my app. What make this difficult is that I don’t want the user to login, but anymway I want to protect my database to be stolen, since there is a lot of work to make it. I thought about making a private / public key, but as you know the application is nothing more than a zip file… is text. Do you think a ip check from server side is a good idea? or something similar? thanks and sorry to be out of topic!!!

  • Webber Wang

    I ran ‘ionic run ios –device’ on a iOS 9 device, the safari console shows ‘Failed to load resource: the server http://tinyurl…’. Inside XCode > Device > Device Console, there is no mention of ‘URL blocked by whitelist error’ either.

    Where can I find this error for iOS device debugging? Thanks!

  • o_mercury

    Hello Nic. Your blog has really been my go to resource in developing my first app with Ionic. More grease to your elbows. I’m having a few issues with developing a feed app for my forum. It gets content from it’s REST api. The issues I’m having are :

    links within the feed are not clickable. They are displayed as plain text.
    In browsers, youtube urls/links embed playable videos dynamically into the web page. Is there any way to this with Cordova?

    I thought these were whitelist issues but I have the plugin as a resource and it hasn’t solved these issues.
    Thanks in advanced for your help.

    • If you’re getting links within your JSON data you need to use regular expressions to parse them into actual HTML links. A URL in plain text of course is not going to be clickable.
      This goes with the last one. You’re going to have to set up your own parsing logic for how to convert URLs to videos.

      Based on what you’ve described this has nothing to do with whitelisting.

  • Mason Radke

    I have been all over the place trying to solve my issue.. Im fairly certain it is related to the CSP.
    I am also pretty sure the problem began when i added:

    .factory(‘repo’, function ($http) {
    return {
    view: function (ID) {
    var url = ‘http://x.x.x.x/Test1/WebService1.asmx/View’;
    return $http.jsonp(url, {
    params: {
    callback: ‘JSON_CALLBACK’,
    ID: ID,
    format: ‘json’,
    }
    });
    },

    Whitelist plugin is installed.
    i have tried so so many different Meta CSP tags. currently:

    in config.xml

    works great in ripple. no data returned on the android device.
    i had a couple other angular http calls before adding the one i posted. They did not pass a parameter, but app worked fine on android devices and ripple then.

    I develop in VS2015 on a VM (possible USB issues), how can i debug the app running on the phone? im sure it would help if i could see some sort of error message. Thank you so much for any help.. tired of being stuck!

  • rohan kangale

    Hi Nic,

    Really good post.Well, i am facing some issues when trying to install and run the app on my mobile device.

    I have created the server side using express + node + mongo. Since i was getting CORS issue, i added the following code:

    app.use(function(req, res, next) {
    res.header(“Access-Control-Allow-Origin”, “http://localhost:8100”);
    res.header(“Access-Control-Allow-Methods”, “GET,PUT,POST,DELETE,OPTIONS”);
    res.setHeader(‘Access-Control-Allow-Headers’, ‘X-Requested-With,content-type, Authorization, Access-Control-Allow-Origin, Access-Control-Allow-Headers’);
    res.header(“Access-Control-Allow-Credentials”, “true”);
    next();
    });

    Above, http://localhost:8100 is the local system from where my ionic app is running. I am making the request as :

    var request = $http({method: ‘GET’,url: ‘https://domain_name.users.io/data/list’},withCredentials: true});
    return request.then(function(response){});

    Above, domain_name is the domain from where i am accessing the data.

    Well, i am able to access data when i run the application on browser.

    I created an .apk file, installed it on my mobile device. But not able to access the data.

    Could you help me out with the issue ?

    • The http://localhost:8100 tells me you’re using ionic serve, ionic live reload, or ionic view. Don’t use those when developing a mobile application.

      Best,

      • rohan kangale

        Thanks for you reply.
        So what if i deploy my front-end code too on cloud/server. And if i do so, would i able to create an .apk file of it and use it on my mobile device ?

  • sflomenb

    I cannot get whitelisting to work for “mailto:” links. I have in my config.xml. Any ideas?

    • RagnarDanneskjöld

      Yeah – I’ve been running into this issue too. Were you ever able to resolve it?

  • Hi!

    just FYI, I tried your tutorial before adding the plugin and it worked correctly (although the tinyurl result doesn’t work). Maybe something has changed lately…

  • ömer orçun özbay

    hi, I have a question on youtube. please help.