Data Leakage with Cache.db

I was recently alarmed by our Security Testing team Appknox that some Sensitive Information was being saved into SQLite3 Database of my iOS application which is unencrypted and such information in such databases may lead to leakage of data. When I read the report in detail I was shocked to see that my access_token was exposed and was lying in one of the tables.

This was very weird as I was not using any Database by myself, therefore the doubt went straight to third parties that I was using in my application. But NO LUCK, none of the third parties was using any such database to save data. I took some time to examine and would like to share the result here.

Go to Xcode > Window > Devices > Select your app > > Download Container.
Once the container is downloaded, right-click and open the package contents. > App Data > Library > Cache > (Your apple bundle id) > Cache.db.

On a Simulator:

~/Library/Developer/CoreSimulator/Devices/[DeviceID]/data/Containers/Data/Application/[AppID]/Library/Caches/[bundleId]/Cache.db

Now open Terminal and execute
- sqlite3 Cache.db
- .table

There is a table called cfurl_cache_receiver_data. This contains all the HTTP Request responses that my app receives from the API. The problem is this is all the data in this column that is actually responses from the API and not requests I send out. So, URLSession automatically caches the response into Cache.db which can easily be compromised if my device is stolen.

This is perfect example where Many secure applications in the App Store don’t leak data on their own, but still suffer from data leaks because they are subject to Apple’s caching.

When I execute the query on the `cfurl_cache_receiver_data` table, this happens which shook me. All it took was one tiny line:
select * from cfurl_cache_receiver_data;

🧠 Solution:

Since application security is one of my top concerns and working for a bank makes it even more important, the solution was to stop URLSession from caching the API Response in Cache.db somehow.
This can be achieved by telling URLSession’s header to stop caching. Here is the magical line which is self-explanatory.

header.add(name: “Cache-Control”, value: “no-store”)

If you want to read more about Application Security, I would really encourage you to go through this amazing article I found. Adios