Problem (and solution): Any AIR app can read any other app’s databases

Posted June 21, 2007 11:06 am
Filed under: AIR, Application Design, Articles by Paul, Tutorials, local SQL database

In a side note on a recent post about the AIR functionality for working with local SQL databases, Tim Anderson raised some concerns about the security model for AIR local SQL databases, that I thought would be valuable to discuss more.

Tim also raises other concerns which aren’t so much issues to keep in mind when developing AIR apps as they are issues surrounding the documentation. I’ve attempted to respond to those concerns in a separate post.

Tim says:

unlike [Google] Gears, AIR makes no attempt to isolate databases based on the origin of the application. In AIR, a SQLite database may be anywhere in the file system, and it’s equally available to any AIR application - a big hole in the AIR sandbox.

I think Tim raises an important point (although I disagree a bit with his conclusion). Very soon after I started working with the local SQL database functionality in AIR I realized the same thing — since any AIR database can be read by any AIR application, it means that I can write a database application in AIR, and you can write an application that finds the file I create with my app, and reads its data.

But let’s take a moment to get a little perspective, after which we’ll consider what we can do about it.

It’s true that in AIR, a SQLite database may be anywhere in the file system, and in general it’s equally available to any AIR application. However, while this differs from Google Gears’ approach, there are some key reasons why this difference is allowed, and why it’s not considered a “big hole” security-wise.

First of all, there’s a significant difference between Google Gears and Adobe AIR. Google Gears is an extension to the standard capabilities of web browsers, but ultimately an application that uses Google Gears runs in a web browser and is therefore subject to all the security constraints of a browser-based application. This is similar to content that runs in the Flash Player browser plugin, or in a non-Gears-enabled HTML/JavaScript application — neither of which can freely access a user’s hard drive. Why is that? Well, it’s because all it takes for a user to access a Google Gears application is for the user to visit the url of that application in his or her web browser. That could be by clicking a link, or even by an automatic redirect that the user has limited control over.

On the other hand, an AIR application doesn’t require or use a browser. In order for a user to access an AIR application, he or she must first choose to install the application, including going through a security dialog that will describe whether the application was signed with a security certificate. In this way, an AIR application is comparable to any other desktop application, such as one written in C++. Since any C++ application could theoretically include the SQLite library, installing an AIR application is no different from installing any C++ application in the sense that, by doing so, a user opens himself up to possible abuses and security risks.

Likewise, any application that can read files from the file system (AIR or not) has the same potential for “stealing” sensitive information. If someone has written down his passwords in a Microsoft Word file, an installed application could search the hard drive for all Word files and read them all and send their contents to a malicious author. Even if your application uses a custom binary file format, there’s nothing that can be done to prevent someone else from reverse-engineering your file format and then writing an app that reads your files and extracts the data. Of course, it’s true that by using a SQLite-format database file, in return for the convenience and benefits it gives you, you’re saving Joe Evil the trouble of needing to reverse engineer your file format, and instead you’re handing your data over quite handily in a wonderful structured way.

On the other hand, all this openness actually has benefits. Since my app can read files written by another app, I can write two different apps that can understand each others’ data. If I make a certain kind of app, and later you make another app that does the same thing but does it better, you can read my file format and import my data into your app — meaning you can help users migrate from my crummy app to your awesome one.

Having said all that, I don’t want you to think that I’m simply washing my hands of the issue. I think it’s an extremely important one, and I’m very glad it came up.

Tell me how to fix it, already

All openness aside, if you’re storing sensitive data in your application, data that you don’t think other applications ought to be able to read, there are some things you can do to try to minimize the potential for damage. Note that since the problem isn’t exclusive to apps that use a local SQL database (although it is perhaps more apparent for those apps), the possible solutions aren’t exclusive to local SQL databases either.

Use user-specific directories

Every AIR application has a special folder in the operating system that can be used to store files related to the app. The folder, known as the “application storage directory,” is actually different for different logged-in users of the same application. In that way it’s a convenient way to separate files for different users of your application. It’s location is always available using the File.applicationStorageDirectory property. Similarly, you can access the directories representing the user’s desktop and his/her documents directory; again, these are folders that will be different per-user, but your app can use the same code to access them regardless of who is using the app.

Note that this only provides limited protection. Any AIR app or any other app can traverse the file system (assuming the logged-in user has permission to do so) and discover and read files in the application storage directory or other user-specific directories. So while this might protect files belonging to other user accounts (if the user running the malicious app isn’t an administrator), it won’t protect files belonging to the logged-in user.

Encrypt your data

The most reliable way to protect sensitive data from other applications is to encrypt it. This can be done in a couple of ways:

Note that in both of these cases I’m talking about using a two-way encryption algorithm. Typically such algorithms require you to have some sort of secret — the encryption key — that is used by the application to encrypt and decrypt the data. Since an AIR app consists of HTML and JavaScript files (plain text) and/or SWF files (binary, but known to be de-compileable), you won’t want to store the encryption key for your application within the source code of your application. Rather, you’ll want to generate the key for each user, and store it separately from the application data. Christian Cantrell’s “Salsa” application demonstrates how to do this (it actually uses a user-selected passphrase as the encryption key, although the release notes say that future versions won’t require that) so that’s an example app to look at for an example of two-way encryption.

Not just reading

On a somewhat related note, another concern with other applications being able to access your app’s data has to do with the integrity of the data. Not only could another app read your application’s data, but it could just as easily change the data as well. Apart from two-way encrypting the entire database file, there isn’t really any way to protect against this. If you don’t want to encrypt the entire database file, one way you can at least verify the integrity of your data is by using a one-way encryption algorithm (also know as a hash). It works like this:

  1. After closing your database, your app encrypts all or some of your database (either the bytes of the db file, or the db data) using a one-way encryption algorithm.
  2. The next time your app opens your database (or before opening the db if you hashed the file itself) you run the same file (or portion of the file or data) through the encryption algorithm again.
  3. If the source data (your db’s contents) hasn’t changed, the resulting hash value should be identical. If the contents of the database have changed, the resulting hash value will have changed — meaning the data has been tampered with by something other than your application.

You could even combine an integrity check with two-way encrypting the file. For example, you could create a hash of all or part of the database file, then append the result to the file. When you reopen the file, you would need to extract the hash, then you could compare it to the rest of the database as well as using the database file (minus the hash) for your application.

Finally, I should acknowledge that, while I’ve done some study of encryption and securing applications, by no means do I consider myself an expert on the topic. If anyone has other ideas, suggestions, and especially if you see some issues with the techniques I’ve recommended here, please share your experience!

You can leave a comment, or trackback from your own site.

10 Comments so far


  1. Kaizenlog is reported to have said:

    links from Technoratihttp://www.anthropology-iran.org) with the collaboration of Ethnodoc create jointly a new online database and archive for Iranian anthropological and documentary films. … Anthropology.net - http://anthropology.netProblem (and solution): Any AIR app can read any other app’s databasesBy Paul unlike [Google] Gears, AIR makes no attempt to isolate databases based on the origin of the application. In AIR, a SQLite database may be anywhere in the file system, and it’s equally available to any AIR application - a big hole in the


  2. Tim Anderson’s ITWriting - Tech writing blog » Abobe AIR security concerns is reported to have said:

    […] AIR security concerns By Tim Adobe’s Paul Robertson has a thoughtful response to my complaint about AIR security. The point I made is that any AIR application has the same […]


  3. JD on EP is reported to have said:

    AIR, security…

    AIR, security: I missed this in MXNA yesterday and don’t see many links yet, so a little bump might be useful. Paul Robertson, a technical writer on the Adobe Integrated Runtime team, discusses the different ways to locally store sensitive data. The b…


  4. Jens Anders is reported to have said:

    Good information, but I have one question for you.
    How would you suggest that the secret key and hash is stored?
    From what I can see they would proberably be just as vournerable as the db itself.

    Is there a way in Air to save strings to the Air runtime environment that only that application can read?
    I’m thinking that something like an application scope or registry would be a great thing..
    Maybe Air.applicationVariables.secret = “something”; or
    Air.appRegistry.secret = “something”; ?


  5. Armin is reported to have said:

    This article very help me. thank’s


  6. Ed Rowe is reported to have said:

    Jens -

    Yes, use the EncryptedLocalStore API to store information that only the application can read.

    Ed Rowe
    AIR Team


  7. Adobe - Flex Builder 3 Forums is reported to have said:

    Kramer auto Pingback[…] Hi herbat,You can find more here:http://probertson.com/articles/2007/06/21/securing-air-sql-database/ […]


  8. Air & scurit - Centre de Formation Flash - Forums Adobe Flash is reported to have said:

    Kramer auto Pingback[…] Hello,Pour ce qui est de certaines infos sensibles, login, pwd … Tu peut utiliser : EncryptedLocalStore-> http://livedocs.adobe.com/labs/flex3/langr…LocalStore.htmlexample : http://blog.kevinhoyt.org/2007/10/23/encry…l-store-in-air/un petit article interessent : http://probertson.com/articles/2007/06/21/…r-sql-database/ […]


  9. sohbet is reported to have said:

    Is there a way in Air to save strings to the Air runtime environment that only that application can read?
    I’m thinking that something like an application scope or registry would be a great thing..
    Maybe Air.applicationVariables.secret = “something”; or
    Air.appRegistry.secret = “something”; ?


  10. Paul is reported to have said:

    @sohbet:

    As others have noted, you can use the EncryptedLocalStore class for that functionality.

Add your comment





Comment notes

Please keep comments on topic. Comments that are inappropriate or offensive will be edited or removed.

Paragraphs and line breaks are automatically converted to HTML, and quotation marks are converted to “smart” quotes.

The following XHTML tags can be used: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> . All others will be removed.

Articles by Type

Articles by Topic

Random Reading

Currently...

Subscribe