# From TOF : Saving and loading private iOS app data

**URL:** <https://ifnotnil.com/t/from-tof-saving-and-loading-private-ios-app-data/3392>\
**Category:** Other\
**Created:** [14 July 2023 18:43 UTC](https://ifnotnil.com/t/from-tof-saving-and-loading-private-ios-app-data/3392 "2023-07-14T18:43:25Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![DaveS](https://ifnotnil.com/user_avatar/ifnotnil.com/daves/32/79_2.png) [@DaveS](https://ifnotnil.com/u/DaveS)\
**Post date:** [14 July 2023 18:43 UTC](https://ifnotnil.com/t/from-tof-saving-and-loading-private-ios-app-data/3392/1 "2023-07-14T18:43:25Z")

</div>

```auto
[Jeffrey Massung]
My iOS app goes through a login process to eventually be given an authentication token that can be used for a period of time (e.g. 24 hours) before it expires and a new one is needed.

What I’d like to do is save that token somewhere on the device that only my app has access to so that the user can quit, reload, and get access to it using FaceID/thumbprint and only have to re-authenticate if the token has expired.

I’m not finding any sandboxed storage location (or functionality) that only my app has access to. I suppose I could write directly to the drive and encrypt the data, but I’d prefer not to if there’s something already built-in for this use case.

[Greg O]
Typically you would store this type of info in the keychain.

```

**NO**. simple items should be stored in UserDefault.standard (a Plist)  
Large amounts of data should be in a textfile or Sqlite Database in either /Documents or /Application Support

---

<div class="post-metadata">

**Author:** ![npalardy](https://ifnotnil.com/user_avatar/ifnotnil.com/npalardy/32/10_2.png) [@npalardy](https://ifnotnil.com/u/npalardy)\
**Post date:** [14 July 2023 18:53 UTC](https://ifnotnil.com/t/from-tof-saving-and-loading-private-ios-app-data/3392/2 "2023-07-14T18:53:38Z")

</div>

this is more like an access token/key  
that should be in keychain shouldnt it ?

I truly haven’t kept up on where apple says

Is UserDefault readable by ANYTHING else ?  
if so that might be undesirable for a secret key like this

---

<div class="post-metadata">

**Author:** ![DaveS](https://ifnotnil.com/user_avatar/ifnotnil.com/daves/32/79_2.png) [@DaveS](https://ifnotnil.com/u/DaveS)\
**Post date:** [14 July 2023 19:05 UTC](https://ifnotnil.com/t/from-tof-saving-and-loading-private-ios-app-data/3392/3 "2023-07-14T19:05:18Z")

</div>

No user default is not readable by anything else (or if it is, it is not easy) as this (and /Documents even) are inside the sandbox.

I would be that Keychain has a more global access on iOS, but I could be wrong there

---

<div class="post-metadata">

**Author:** ![npalardy](https://ifnotnil.com/user_avatar/ifnotnil.com/npalardy/32/10_2.png) [@npalardy](https://ifnotnil.com/u/npalardy)\
**Post date:** [14 July 2023 19:08 UTC](https://ifnotnil.com/t/from-tof-saving-and-loading-private-ios-app-data/3392/4 "2023-07-14T19:08:47Z")

</div>

Apple _seems_ to suggest this is a good place to put such a thing

> **[Keychain services | Apple Developer Documentation](https://developer.apple.com/documentation/security/keychain_services/)**
>
> Securely store small chunks of data on behalf of the user.

> Computer users often have small secrets that they need to store securely. For example, most people manage numerous online accounts. Remembering a complex, unique password for each is impossible, but writing them down is both insecure and tedious. Users typically respond to this situation by recycling simple passwords across many accounts, which is also insecure.

NOW whether they also have recommendations about UserDefault.standard I dont know

This _shouldnt_ according to the poster on TOF, be readable by other apps  
UserDefault.standard seems like it may be

---

<div class="post-metadata">

**Author:** ![DaveS](https://ifnotnil.com/user_avatar/ifnotnil.com/daves/32/79_2.png) [@DaveS](https://ifnotnil.com/u/DaveS)\
**Post date:** [14 July 2023 21:02 UTC](https://ifnotnil.com/t/from-tof-saving-and-loading-private-ios-app-data/3392/5 "2023-07-14T21:02:34Z")

</div>

UsersDefault to the best of my knowledge is App specific and inside the Sandbox… While I believe that the keychain is System accessible and outside the sandbox…

---

<div class="post-metadata">

**Author:** ![npalardy](https://ifnotnil.com/user_avatar/ifnotnil.com/npalardy/32/10_2.png) [@npalardy](https://ifnotnil.com/u/npalardy)\
**Post date:** [14 July 2023 21:25 UTC](https://ifnotnil.com/t/from-tof-saving-and-loading-private-ios-app-data/3392/6 "2023-07-14T21:25:16Z")

</div>

User defaults just seems deliberately less secure - certainly doesnt require user authorization to access it which Keychain does  
On macOS any other app _could_ ask to read them and the system will permit it

- edit - SOMETIMES (see below)  
Hence why you’d use keychain on the desktop

~~iOS I don’t know if the API’s isolate UserDefaults the same way~~  
~~They might~~  
~~~~  
~~Which might mean on iOS _either_ could work~~

> [@](#):
>
> A sandboxed app cannot access or modify the preferences for any other app, with the following exceptions:
> 
> - App extensions on macOS and iOS
> - Other apps in your application group on macOS

> **[UserDefaults | Apple Developer Documentation](https://developer.apple.com/documentation/foundation/userdefaults)**
>
> An interface to the user’s defaults database, where you store key-value pairs persistently across launches of your app.

so yeah they seem isolated from other apps meaning you could probably use either keychain or user defaults  
one will be stored encrypted (keychain) - the other wont necessarily be stored encrypted

---

<div class="post-metadata">

**Author:** ![samRowlands](https://ifnotnil.com/user_avatar/ifnotnil.com/samrowlands/32/121_2.png) [@samRowlands](https://ifnotnil.com/u/samRowlands)\
**Post date:** [15 July 2023 02:04 UTC](https://ifnotnil.com/t/from-tof-saving-and-loading-private-ios-app-data/3392/7 "2023-07-15T02:04:13Z")

</div>

If I may.

The Keychain is an encrypted file and trying to read data from a different application requires keychain owner approval. If an app has access to a device file system, the keychain file is unsuable.

UserDefaults are written to storage as a plist (may be text or binary) any credentials are written out as plain text. If the file system is compromised so are any credentials stored there.

The App Sandbox by default locks down the file system, but can be escaped. You shouldn’t need to worry about this with App Store apps (but you also cannot ensure that the app you run doesn’t have a Sandbox escape).

Notes:  
If the Sandboxed application is signed with the same Team ID as the targeted application and has the right entitlements, the customer may not get asked to approve Keychain access. Even then the request dialog can be confusing, I see this all the time.

In theory, a Sandbox escape is more likely if the attacker has direct access to the device and can manually install an application without it being approved by the App Review.

IIRC it is also possible for a Sandboxed application to have entitlements which would allow it to read other applications UserDefaults, again it needs to be signed with the same TeamID as the targeted application.

In summary, my honest advice would be to encrypt the token myself, this will negate either of these possibilities and would require the app to be debugged to see what the encryption parameters are.

Which increases the workload to compromise a social media account, while it may actually be easier to simply brute force an account or use a phising scheme to obtain credentials.
