Sensitive Information Disclosed on the Application Memory

Hi Team,

The user token/passwords and details are still available in memory after submission in my IOS mobile application.

This allows for an attacker with physical access to the user's system to access the memory and steal the credentials. I was able to extract the user details with fridump. https://github.com/rootbsd/fridump3

The clear text details in the memory should be reset after computing the hash on the login function.

A simple recommendation there is:

It's recommended to clear sensitive values and set as the null values from application memory after they are used.
Also, it's recommended to not store sensitive values (such as password) as plain text values, as a mitigation hash/XOR function can be used.

Technically it makes sense (at least from my experience using other languages such as C / C++ / C# / Objective-C / Java etc..). However, apparently Swift has some strange runtime mechanism of caching strings in memory. Meaning that even if you remove the content or modify a string in memory, its content will still be cached somewhere in memory, either as leftovers or copies (see images below). I’m familiar with the concept of automatic reference counting in ObjC and Swift, but for Swift specifically it seems to be more than that.
In Objective-C and C in general, I never had this issue, because it’s allowed to have more control from the developer perspective, such as writing C code in Objective-C (e.g. calling memset on a heap allocated string).

Reading some threads: https://developer.apple.com/forums/thread/106405 https://developer.apple.com/forums/thread/44121 https://developer.apple.com/forums/thread/4879 https://stackoverflow.com/questions/60702113/how-to-remove-the-string-from-the-memory-for-security-reasons-in-ios-is-it-even/

The last comment there by eskimo from the 2nd thread is the same thought process I had. Eventually a Text Field requesting you to enter a password will return a copy. Even if we use Unsafe Swift features, eventually a Text Field will return a copy of a string from a safe context. I was thinking even creating a custom UI control where it will override some of the text change events and store them on a static buffer where each character is XORed, meaning that even if we get the text from the custom UI control somewhere in the consumer code, it will return a copy, but an encrypted XORed string of the user’s password.

So, what's your thoughst? What's the solutions ?

Post not yet marked as solved Up vote post of uceka Down vote post of uceka
2.3k views

Replies

The threads you've linked to are fairly comprehensive - it's difficult.

As a "thought experiment", here is how I would do it:

  • Create a UIView that implements UIKeyInput (in objC or Swift). https://developer.apple.com/documentation/uikit/uikeyinput?language=objc
  • Draw *s as the user types characters. (The fact that you're not displaying the password as it is typed is a great help!).
  • As you receive characters one-at-a-time, pass them to some C code that appends them to a C char array.
  • Compute your hash of the C array, and then zero it.

Or, maybe your hash function can process the characters as they are received, so there is never a copy of the partial password in memory. This does make backspace more difficult though!

So what will you see in memory if you dump it after that? It's likely that you'll find the NSStrings for the individual insertText calls. If you're lucky, they will be out of order and mixed up amongst lots of other NSStrings. If you're unlucky, they will be stored contiguously next to some obvious clue about what they are.

I was able to extract the user details with fridump.

To be clear, that requires active cooperation on behalf of the user:

  • They either have to apply unsupported modifications to their device (jailbreak it).

  • Or they have to run a development version of the app.

Under those circumstances an attacker doesn’t need to extract strings from memory, they can just catch the password as the user types it.

You need to think carefully about your threat model before you allocate a bunch of time to ‘fixing’ this problem. Would you, perhaps, be better off using that time to implement App Attest?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

that requires active cooperation on behalf of the user

What happens if someone steals the phone? I'm curious as to whether the phone would need to be cracked in advance in order to dump the RAM in this way, or whether it can be done afterwards.

You need to think carefully about your threat model

I think the main threat model is probably "we have this list of security best practices and I'll get fired if we don't comply with them".

What happens if someone steals the phone?

I’m not the right person to enumerate the security features of iOS. You should feel free to explore these scenarios independently. Take an iPhone for which you have no privileges [1] and try to scrape its memory. If you succeed, you could earn some bucks!

I think the main threat model …

I’m not able to help you defend against threats from your management (-:

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] That is:

  • You don’t know the passcode.

  • It’s not already paired with your Mac.

  • It has Developer Mode disabled (on iOS 16 and later).