Securing Ionic/Cordova mobile applications

January 9, 2018, 9:00 am Categories:


How many of you know that the source code for your mobile applications can be inspected by any user who downloads them? How many of you are aware that any content that you place within your Ionic/Cordova applications is able to be read by others (with little effort)?

Would it pain you to learn that 100% security is IMPOSSIBLE?

Does that mean that your app can't be protected? That your development efforts are all for naught?

No - but there are caveats and challenges.

Over the course of this article I want to discuss some possible approaches to helping secure your Ionic/Cordova apps and minimise the possibility of code tampering and malicious usage.

I want to stress from the outset that I am NO security expert, that this is just as much a learning experience for me as it might be for yourself (and should any readers have further suggestions on this subject please feel free to share those in the comments section underneath this article).

Additionally, given the nature of Ionic/Cordova apps (as well as native apps) it should always be assumed that their contents are able to be inspected and that a truly determined attacker will do everything possible to crack whatever security might be in place.

Our job as developers is to try and deter such attempts from being successful.

With that said let's look at certain ways in which we can help significantly lesson malicious attacks, harden our applications and hopefully minimise (because we can never eliminate this completely) the possibility of code tampering and the reverse engineering of our application logic...

Keep your secrets safe

Sensitive business logic (such as passwords and API account keys/values) should, as far as is possible, be stored on a secure server and not within the application codebase.

Note in the previous paragraph that I stated the following - as far as is possible.

The reason for this caveat is that there may be circumstances where we simply cannot avoid this - such as, for example, placing the firebase web initialisation code within our application (where firebase is concerned though this can be obviated by implementing an authentication flow to allow users to access the application data only if they supply the correct credentials - we'll discuss server side approaches a little later on in this article).

Where we have no choice but to implement sensitive business logic inside our Ionic/Cordova applications we might want to shift as much of this logic into an SQLite database as possible and explore using encryption with the following:

Disclaimer: I have NOT personally tested or used this tool as yet so I have NO idea how feasible or effective this might be.

I have however experimented with Cordova Crypt but could not get this to encrypt my Ionic www directory when the application was published to an .ipa file for iOS. Whether this was due to a mistake on my part or not I don't know but feel free to explore and play with this plugin if you fancy a challenge.

As a general rule of thumb where security is concerned always treat your application as if it were a website and assume that your code is able to be inspected by others.

Manage your Content Security Policy

If an attacker discovers a vulnerability with code used in an application (say for example a third party API call or a JavaScript library) then they might find ways to exploit this so that malicious code is run within the application instead.

The Content Security Policy (CSP) meta tag was introduced to help prevent such attacks by defining which network requests are allowed to be made and where resources are loaded from.

This meta-tag is placed within your application's index.html file - an example Content Security Policy might look like the following:

<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap:; style-src 'self' 'unsafe-inline'; media-src *">

These rules are constructed to allow the application to manage security/resource access as follows:

  • default-src 'self' - matches current source but not subdomains
  • data: - defines the source scheme for loading resources
  • gap: required for JavaScript to native device communication and is used solely for UIWebView on iOS
  • - required solely for Android to allow Talkback to function properly
  • 'unsafe-inline' - allows inline JavaScript and CSS
  • 'style-src' - allows all stylesheets from current source
  • media-src * - allows all video and audio sources to be accessed

A Content Security Policy is dictated by what network access the developer requires for the application.

If, for example, the developer wanted to only allow XHR access via https they might include the following CSP:

<meta http-equiv="Content-Security-Policy" content="default-src 'self' https:">

Or, if they required access to a specific set of social media resources - such as Google, Facebook & Twitter - then their CSP might look like the following:

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src; child-src">

When constructing your application's Content Security Policy be aware of the consequences of certain rules on access to particular resources. If you're not careful you might find yourself blocking certain resources that your project requires - so be very discriminating in what you use here.

Further information on Content Security Policy and here.


You'll notice that Ionic applications for iOS & Android also make use of Cordova's Network Whitelist Plugin to provide cross site scripting protection for webviews that don't support CSP. This plugin allows developers to implement the following access controls within the application's config.xml file:

  • Navigation (defines which URL's the webview can navigate to - by default only file:// navigations are allowed)
  • Intents (defines which system communication protocols the application is allowed to access)
  • Network requests (defines which network requests are allowed to be made - I.e. XHR, images etc)

The following demonstrates how these could be added to the config.xml file:

<!-- Define navigation access -->
<allow-navigation href="https://*/*" />

<!-- Define intents -->
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />

<!-- Define network access - VERY insecure setting (allows access from ANY source) -->
<access origin="*" />

It is recommend though that a Content Security Policy is used for network requests as it is seen as more secure than relying on the whitelist plugin rules for controlling network access.

Further information on the Cordova whitelist plugin.

Code obfuscation

Code obfuscation describes the deliberate act of transforming application logic into unrecognisable code that is difficult to disassemble/understand but still provides the same functionality that it did prior to being obfuscated.

For example, if I use this free tool I can paste in the following JavaScript:

function hi() {
  console.log("Hello World!");

Which, upon obfuscation, will result in the following code:

var _0x1d57=['Hello\x20World!','log'];(function(_0x3191bc,_0x54fa91){var _0x1d4fd3=function(_0x596a55){while(--_0x596a55){_0x3191bc['push'](_0x3191bc['shift']());}};_0x1d4fd3(++_0x54fa91);}(_0x1d57,0x135));var _0x5cfd=function(_0x523c75,_0x2dbd21){_0x523c75=_0x523c75-0x0;var _0x247d55=_0x1d57[_0x523c75];return _0x247d55;};function hi(){console[_0x5cfd('0x0')](_0x5cfd('0x1'));}hi();

This looks pretty impressive and can help deter the casual snooper but it's important to realise that code obfuscation does NOT make your code secure as it can still be accessed by interested parties. The intent with obfuscation is to make it much more difficult for those parties to be able to steal and use your code.

Unfortunately almost all JavaScript obfuscation can be easily reversed thanks to various services/programs that are available with even the most casual Google search on the subject.

An interesting solution that applies higher level security to obfuscated code is JScrambler which, although pricey, does offer some interesting features such as polymorphic obfuscation and code traps.

If you're looking to develop commercial and/or enterprise-level applications (where security is an absolute priority in protecting your product's source code as well as your client's business) then JScrambler definitely merits investigation.

Developing for Android? Then Android ProGuard is a popular choice with developers looking to obfuscate their application code but, as with most obfuscation tools, it offers minimal code protection against reverse engineering.

As a security solution code obfuscation on its own provides no protection whatsoever but, if combined with other approaches, it can form part of a defense in depth strategy (the ideal being to make it so difficult for an attacker to change your source code that they become discouraged and simply give up).

JSON Web Token

One security concern with transmitting data between parties can be summed up as follows:

  • Is the sending party who they say they are?
  • Has the data been tampered with en-route?

One approach to helping solve this dilemma is JSON Web Token.

JSON Web Token (JWT) is an open standard that defines how information can be securely transmitted between parties as a digitally signed, compact JSON object. Due to their small size JWTs can be transmitted quickly through a POST parameter, inside HTTP headers or via URL.

A JWT consists of three parts, separated by dots, which are:

  • Header (the first part of the JSWT which typically consists of the token type - I.e. JWT - and the hashing algorithm being used - I.e. RSA, HMAC or SHA256)
  • Payload (the second part of the JWT and this contains the claims, or statements, about the user as well as additional metadata)
  • Signature (the final part of the JWT which is used to verify the sender of the JWT and to ensure the message wasn't tampered with during transmission)

As JWTs can be digitally signed this makes them ideal for securely transmitting data between parties (as the digital signature is calculated using the Header and Payload of the JWT itself the client is able to trust that the sender is who they say they are and that data hasn't been tampered with by an unknown third-party).

More information on JSON Web Token.

Server side integration

As far as protecting sensitive business logic is concerned moving this from your application codebase to a secure server (the emphasis is on secure here) is the safest and most secure method of protection from prying eyes.

To truly make this approach effective an Ionic/Cordova application should implement an authentication/authorisation based system to validate, verify and, upon successful completion of the process, grant user access to protected routes or resources on their secure server.

In this context the use of JSON Web Token would be ideal for user verification and ensuring data integrity (I.e. no tampering of data in transit) during client/server communication.

Alternatively a BaaS (Backend as a Service) platform such as Firebase can help handle the authentication flow (although user verification would have to be independently handled by additional logic courtesy of the developer).

Additionally the implementation of HTTPS/SSL Pinning allows the authentication/authorisation process to avoid man-in-the-middle attacks as all data transmission will be encrypted from the application right through to the server itself.

Where SSL Pinning is concerned the Ionic Native HTTP plugin can be configured for this purpose.

Validate, filter and sanitise your data

Your application data will typically come through a variety of sources; third-party API calls (typically social media integration with Twitter, Facebook etc), data generated content (I.e. via LocalStorage/SQLite or from BaaS providers such as Firebase) or provided through user submitted content (such as blog comments, form submissions etc).

With this in mind it's important that this data is validated prior to being stored/used within your application as the potential for XSS attacks, SQL injection and similarly malicious behaviour is too great to ignore.

At a bare minimum developers should observe the following rules when working with data:

  • Filter HTML tags from user submitted content (or, where necessary, limit such tags to a specific subset such as those used in text formatting - I.e. paragraph, strong and em)
  • Ensure that submitted/retrieved data that is to be stored within a database matches the correct data type for each field (to avoid data corruption. data loss issues etc)
  • Use prepared statements when working with SQLite to avoid SQL injection attacks

Using the Ionic Native SQLite plugin we could use prepared statements to add data to an SQLite database in the following way:

// The prepared statement is structured in the following way:
// 1. The SQL query - INSERT INTO tableName (name, description)
// 2. The SQL binding placeholder for each field value (represented as a question mark) - VALUES (?, ?)
// 3. The value to be inserted (stored within an array) - [name, description]
let sql     = "INSERT INTO favouriteSoftware(name, description) VALUES(?, ?)",
    data    = [name, description];

this._DB.executeSql(sql, data)
.then((res) =>
  console.log('res.insertId: ' + res.insertId);
  console.log('res.rowsAffected: ' + res.rowsAffected);
.catch((error) => {
  console.log('SELECT error: ' + error.message);

That's a lot of different options we've covered and it's really a case of each developer understanding their application's requirements and then choosing the most appropriate combination of security measures to protect their code from prying eyes and avoid falling prey to SQL injection, Cross Site Scripting attacks and other such naughtiness.

In summary

100% security is an impossibility given platform vulnerabilities, software bugs, the continuing evolution of digital technologies (and the discovery of specific attack vectors) and last, but certainly not least, developer knowledge (which might contribute to security mistakes without realising it - and yes, I consider myself very much on a learning journey as far as this topic is concerned).

That's not to say we should throw up our hands in resigned defeat and despair but it does mean we need to be very aware of the tools we use and the code that we write so as to not introduce security issues that could otherwise be avoided.

Staying abreast of technology/security developments and remaining vigilant with the different requirements of our own projects (particularly where it comes to data management and integrating third-party API's, plugins and libraries) should help guide and inform the development of our applications going forwards.

Hopefully the different approaches discussed in this article will give you some useful starting points to help harden the security of your Ionic/Cordova applications.

What did you think of this article? Was there anything that I missed that should have been covered? Share your thoughts, reactions and suggestions in the comments section below.

If you liked what was written here then please consider signing up to my FREE mailing list to stay updated on further articles and e-books that I have in the pipeline.



Post a comment

All comments are welcome and the rules are simple - be nice and do NOT engage in trolling, spamming, abusiveness or illegal behaviour. If you fail to observe these rules you will be permanently banned from being able to comment.