Security surrounding the iOS shared NSHTTPCookieStorage - ios

I'm struggling to find the exact details on this, so I'm hoping to get some help here. I'm looking for some information regarding the underlying storage mechanism of the iOS shared NSHTTPCookieStorage:
When cookies are stored using the shared NSHTTPCookieStorage, is there any encryption provided by default, such as the use of the keychain services? Or are the cookies simply stored in plaintext using NSUserDefaults?
I understand that the cookies are stored within an app's sandbox, so that other apps will not have access, but is my understanding correct that someone with physical access to the device can easily access an app's cookies and their values (especially if they are stored unencrypted)?
If one had to handle some sensitive data in cookies but wanted to utilise the default cookie handling/storage (shared NSHTTPCookieStorage) of the NSURLSession APIs for instance, what would then be the best option?
Sorry, I know I've asked 3 separate questions but any help on this would be greatly appreciated.
Thanks.

I don't know how cookies specifically are stored, but all application files are encrypted on iOS, with an AES256 key specific to the app. Those keys are derived from other keys that ultimately come from the "secure enclave" within the CPU chip, which will only release the keys when the user unlocks the device. (Apple has a pretty comprehensive security white-paper for iOS that describes this in detail.)
For this reason it's quite difficult to access files on iOS, even with physical access, unless you can get the device's passcode and unlock it. The regular cookie storage is probably secure enough for your purposes.

Related

swift3 - How to protect secret key

I am new of iOS swift 3 development. Now, I am working on a project which needs encryption, message authentication code(MAC) and Hashed-base-MAC. These algorithms require secret keys. I know that it is a bad practice to hard-code the keys inside the code, like:
let key = "secretkeyabc123"
Searched and read some articles like:
In iOS, how can I store a secret "key" that will allow me to communicate with my server?
Since other people may perform reverse engineering, I am finding a way to protect my keys. Requirements:
No hash the key. Time allows to crack it, or with hashed table and dictionary
May not connect to Internet (My app. is an offline app. If your answer needs to connect to Internet. Yes, please point it out. I will think about it)
It is a static key. It may change monthly
It is a symmetry key.
Codes, concept or other things are welcome. Thanks!
Don't store the key at all. Perform a Diffie-Hellman key exchange to start an asymmetrically encrypted channel, and use this channel to send across a symmetric key to the client, which can be used for subsequent client use.
Check iCloud Keychain (based on your tags [ios], [swift], [key]).
It functions as a secure database that allows information including a user's website login passwords, Wi-Fi network passwords, credit/debit card management (though without CVV), and other account data, to be securely stored for quick access and auto-fill on webpages and elsewhere when the user needs instant access to them. They are always stored encrypted using 256-bit AES encryption, are stored on device and pushed from iCloud between devices, and only available on a user's trusted devices.

How to securely store AWS service ids for iOS?

I'm developing an iOS app that uses Cognito User Pools / Federated Identities, Mobile Analytics, and S3 to manage various features of the app, and recently I have become concerned for the security of these features. I already use IAM roles to control the services unauthenticated vs authenticated users have access to, but most of these services use strings (e.g. user pool app client id or user pool app client secret for User Pools, or app id for Mobile Analytics) to give the app access to that service.
What are the best practices to securely store these strings on the device to be used when necessary? Is it even necessary to secure these strings since the app is using IAM roles?
If it is necessary to securely store the strings, I have read that using the CommonCrypto library to encrypt strings before putting them in the keychain is best, but I'm not sure what key to use for encryption since my user needs unauthenticated access to those services. Any advice would be tremendously helpful.
This is a common problem to any mobile app. If someone really wants to, it's not difficult to decompile the app and scrape the keys from it. It's great that you are using IAM roles to restrict feature usage. This will limit the blast radius of attackers, but not necessarily prevent them.
Wth user pools you also get a globally unique identifier which can be used with IAM to restrict what S3 you can use key pre-fixes (which act similar to folders) to limit the objects that users can access to pre-fixes with their unique identifier. You can refer to https://mobile.awsblog.com/post/Tx1OSMBRHZVM9V0/Understanding-Amazon-Cognito-Authentication-Part-3-Roles-and-Policies (Using user pools as the provider, which will use the identity id as the prefix). Depending on how you structure your app you could use this so each user can only modify their own objects. I don't think Analytics has any way of restricting like this... because it wouldn't really make sense for it.
As far as securing your ID's there are things you can do to help mitigate, but there is no fool proof way to prevent someone taking it. You could for instance have the app make a call to your server for the ID... but then an attacker could just call the server. You could encrypt it, which might make it more difficult for an attacker to get, but you have to keep the key somewhere and if the app could get it so could someone who decompiles the app. Unless your app users get some sort of password from outside the app and put it in there isn't a complete way to lock it against attackers.
Hope this helps.

Keychain access in iOS for OAuth tokens

I'd like to use Keychain Services for iOS to store the OAuth access token and refresh token that my app need to perform Web services requests. I've been reading the Keychain Services Programming Guide and I downloaded the GenericKeychain sample code, but I'm getting confused:
Code provided in document is different from the sample code... which approach should I follow?
I read somewhere that you need to enable Data Protection in Member Center for the App ID and its associated provisioning profile. However, I didn't read anything about enabling Data Protection in Xcode for the target's capabilities, and it seems that I could access the keychain anyway... this is weird, but I guess I should enable Data Protection in the Xcode project as well, right? Where is this Data Protection stuff described in Apple's docs? Is it somewhere said that I need to enable it for Keychain management? I don't find it...
Samples I found use the kSecClassGenericPassword class for the keychain items. Since I want to manage OAuth related information, is there any better class I should use? Maybe kSecClassInternetPassword? What is the difference with kSecClassGenericPassword?
Is it recommended to instantiate a kind of KeychainWrapper class, or would it be better to access keychain related methods as class methods?
Thanks in advance
Q3:
According to Apple
documentation
You use Internet passwords for accessing servers and websites over the Internet, and generic passwords for any other password-protected service (such as a database or scheduling application).

Validate if the encrypted data is not tampered

I have a string encrypted using RNCryptor v2.2 ObjectiveC library.
After encryption it is stored locally on iPhone.
When want to get the string back, before decryption, I want to make sure that the encrypted is not tampered (like manually changed a character).
How can I verify this?
Thanks in advance!
The theoretically correct answer to your question is that whatever you do in your app locally on the device, you will not be more sure whether your data has been tampered or not compared to doing nothing. You will need to use an external, reliable agent such as a https web server to store some information about your data.
Let me explain this briefly. iOS already gives sufficient protection to the data of your app with its data sandboxing model assuming that the device of the user in not jailbroken. This means that there is no way to alter the private data of your app (saved in the standard Documents, Caches, etc. folder of your app). On the other hand a malicious user who wants to modify the encrypted information stored in the private folder of your app, can jailbreak the device. In this case he will have access to everything and can read and write any private folders.
Some could say that you can create a hash or a digital signature of your data and store it on the device. But if the device if jailbroken the intruder would have access to everything, including the binary code of your app (Objective-C can be reverse engineered without too much effort) and so the hash generating algorithm, the salt or the private key of your digital signature. So he could easily manipulate the digital signature or the hash as well.
You should evaluate the risk of your data being tampered. How much effort worth tampering your data? If you are storing banking information and count about 1 million of users, you should take seriously the risk that somebody could jailbreak the device, reverse engineer your app and tamper your data. If you are storing session tokens of a photo-sharing app, maybe you can just leave it as it is and trust in the sandboxing of iOS. Also it is very important that jailbreaking the device needs active participance of the user so it is not possible to do it remotely, without the consent of the user. This means that the data can not be tampered without the consent of the user.
If you really need to protect your data then the only way is to use an external service that you trust and that can provide your an external security regarding to the device. You could send your sensitive data to a web server through https, let the web server sign it with its private key and resend to you the signature that you can store calmly wherever you want. Every time you need to access to your sensitive data you could verify the signature of the data (and the validity of the signature with the public certificate of the server). As the private key is stored on the remote server, you can be sure that nobody can access it and it can not be used to sign a tampered data.
RNCryptor includes an HMAC to detect this. If the ciphertext is modified, it will not decrypt. You'll get an error ("HMAC Mismatch").

How to save confidential data on iOS? Keychain or Outh2? Thanks.

As you know many apps use keychain to save user login name and password, but is it really safe? especially on device jail break mode. So another solution is to use Outh2 protocol to save those confidential infomation on server side which needs many changes on both client and server side (for my app).
How do you guys handle this tough issue? Anyone who knows please share and thanks in advance.
Keychain:
It has two level encryption options
lock screen passcode as the encryption key
key generated by and stored on the device)
But when the device is jailbroken its not safe too.
oAuth:
Eventhough you store credentials in server you'll have to save the OAuth TOKEN in client side there is no place better than keychain to store it in client side.So now comes possibility of extracting the TOKEN on jailbroken device.
As far as I know in most apps they use one of these approaches.
If you need those data to be very very secure.
Suggestions:
Store OAuth token in server not in client
Store the Encrypted Credentials in Keychain and store the encryption key in server.This approach would be easy for you since you said adopting OAuth is hard for you.
Note:
There are some open source libraries available which detects if the device you run or app is cracked if so you can take action like deactivating TOKEN,deleting critical resources,locking app etc.

Resources