5

I am facing an issue in an iOS application that uses a UIWebView to render HTML5 code that is part of the application bundle.

This HTML5 code makes ajax requests to our backend which may potentially have sensitive data in them. This is all done over HTTPS and our application never stores the sensitive data. However, when doing security testing for the application, we found that http post requests where being stored in a local SQL Lite database (cache.db) as of iOS 5.

It was easy to manage that, by setting the NSURLCache global object to have zero disk storage, and deleting the file when appropriate.

Now however, it looks like in iOS 6.1 Apple has changed the implementation again, and the data is being stored in cache.db-wal. I have limited knowledge of SQL Lite, but I think this is a file created when SQL Lite is initialized with certain options.

Any suggestions as to a fix?

bummi
  • 27,123
  • 14
  • 62
  • 101
Casey
  • 184
  • 1
  • 3
  • 10
  • 1
    A bit more information about the disk caching of url requests. http://petersteinberger.com/blog/2012/nsurlcache-uses-a-disk-cache-as-of-ios5/ – Casey Jul 16 '13 at 05:59
  • Experimentation in our shop suggests that setting "Cache-Control : no-cache, no-store" can prevent the caching. We're still double-checking, though. Please keep keep everyone updated on the status of this. – Hot Licks Jul 18 '13 at 18:04

4 Answers4

5

After further research, it seems that the suggestion by Hot Licks above was correct, by adding the "no-cache, no-store" value to the HTTP response, the HTTP request values where not logged in the SQLite database.

For example, in ASP.Net MVC:

public ActionResult PostSensitiveData(string data)
{
     Response.Cache.SetCacheability(HttpCacheability.NoCache);
     Response.Cache.SetNoStore();

     return Json(data);
}
Noam M
  • 3,156
  • 5
  • 26
  • 41
Casey
  • 184
  • 1
  • 3
  • 10
1

The other files created by SQLite (-journal, -wal, -shm) are part of the database itself.

When you delete the cache.db file, also delete any cache.db-* files.


To prevent that data gets inserted in the first place, open the database and create some trigger like this on every table:

CREATE TRIGGER MyTable_evil_trigger
BEFORE INSERT ON MyTable
BEGIN
    SELECT RAISE(IGNORE);
END;

(And then check whether the UIWebView blows up when the inserted records don't actually show up …)

CL.
  • 173,858
  • 17
  • 217
  • 259
  • I don't accept that as an ideal answer, though it will definitely work. Here is the thing, Apple has broken the Http 1.1 contract by caching data like this without regard to cache control, and they are caching data on http posts! – Casey Jul 16 '13 at 07:14
  • If I delete the cach.db-* files, they are still created, and at least for a period of time, the sensitive data is written to the device and is vulnerable. It's rather easy to retrieve this info using tools like iExplorer and notepad if you can gain physical access to the device. – Casey Jul 16 '13 at 14:32
  • that's a very creative answer, and although it seems a bit hacky, it will probably be the best option. I've done extensive research on this and there is little information. I suspect there are a ton of applications out there that are affected by this and expose sensitive information in the NSURLCache db. – Casey Jul 16 '13 at 18:11
1

You can call

[[NSURLCache sharedURLCache] removeAllCachedResponses] 

This will clear all the cached url calls from the Cache.db file.

Wise Shepherd
  • 2,228
  • 4
  • 31
  • 43
0

I struggled on the same issue. Since I was using react-native, I felt that the current answer were inconvenient. So, I came up with two solutions:

  1. Use this package https://github.com/qq273335649/oa-react-native-clear-cache Then using the function clearCache. The problem is that it erases all the cache, not necessarily convenient.
  2. After the queries that saves the confidential data in the cache, I remove the db-wal file with the package expo-file-system (you need to be using expo for this one)

I hope it helps.

Gyl
  • 61
  • 6