Can iphone users delete your app's keychain data? - ios

To contextualize the question, our use case is an app through which users can get free promotional items on signup. We would like to prevent abuse of the system by limiting to one promotion per device. Since we can't access the UDID, we need some other (mostly) reliable way to check if the phone has already signed up an account. We don't need a solution that is impossible to circumvent, just one that is highly inconvenient to circumvent.
If we store a unique key in the user's keychain, then we'll be able to read it again even if they uninstall and reinstall the app. We're considering using this method to track devices that have already signed up accounts.
Questions:
Is there a relatively easy way that the user could delete or change our app's keychain data? You can assume that the user's device is not jailbroken, and that they will not go to the trouble of completely reinstalling the OS.
What are other options besides using the keychain we might consider? Keep in mind that the app communicates with our server during signup, so we can store previous signup information of any kind on the server.
Are there any gotchas or problems with the keychain method we should know about?

Related

Preserving Keychain data during developer account migration

I am migrating our organisation's app to a new developer account, for internal reasons. I've learned that upon transferring the app to the new account, and after we release an update for the app from the new developer account, we will incur a one time loss of keychain data.
My concern is, that we cannot afford this loss of data. Due to security reasons and nature of the type of clients using the app.
So my question is 2 part;
1) Is there any way that I can prevent this keychain data loss?
2) If not, what are the alternate strategies I can use to prevent the users from getting logged out during this transition?
Assuming you're talking about a real, full App Transfer I don't think this is possible. Keychains are not just differentiated via the app ID, but also the organization's ID (or more precisely the organization's ID is part of an app ID). Since the app's ID de facto changes with a transfer, iOS will prevent it to look up its old keychain. Not even app groups get around this, as a group cannot consist of apps by different organizations AFAIK. Apple would need to implement a kind of exception to this for at least a certain "migration period", but I doubt that will ever happen (for security considerations).
The only way to circumvent a re-login so that the transferred app can save the credentials in its "new" keychain would be to first have an update for the old, not-yet transferred app and have it save the credentials elsewhere, then have the transferred app look them up from there. I'd strongly recommend against this for security reasons, but if you absolutely must do that, you could upload the credentials somewhere secure (via an encrypted connection, obviously, i.e. SSL). You might even be able to use shared web credentials for this, but I haven't looked into that too deeply, so I am not sure whether both apps can be configured to be associated with that website (they're coming from two different teams, after all, but it might be allowed).
Even then, some users might "miss" the update of the older app before the transfer (and update to the "new" one), then they would have to re-login anyways.
If you follow this idea, be aware that you're "moving around" users' private data in a new way! Considering the recent GDPR fuzz this might even have string legal implications, so check with your company's legal advisors about this, too!
1) There is no way your can prevent data loss, since the App ID Prefix has changed during app transfer TN2311 > A one-time loss in keychain data will occur if you switch your App ID prefix
2)
If you application utilizes Push Notification, you can use the APNs device tokens to remap the user account.
Once the new app is launched:
Send the device token to server
Find the username from your database
Generate a session token (add your own security design here)
Save username + the token in your new Keychain
For those who doesn't allow notification, just force them to relogin

How to ban an iOS user?

A while ago, I got banned from an iOS app. Not a user ID ban, but it seems to have been a device ban. Even if I delete and reinstall the app and try to make a new account, it would automatically get banned. My question is, how are they doing this? What are all the possible ways to ban a device that is persistent even after deleting and re-installing the app?
It is not possible to access UDID anymore, so there's that. And I don't think iOS allows them to view iTunes account, so that's not possible. Are they perhaps storing anything in the keychain? From what I know, some things in the keychain don't get removed even if the app is uninstalled.
I'd like to implement something like this in my app, so I want to know all the possible methods, with pros and cons for each.
When the app is uninstalled, all data goes with it. So writing anything to disk isn't going to work.
You can store something in the keychain, although users can edit the keychain if they sync it to a mac. That makes it pretty insecure.
The best option is to store it off the device, in iCloud. I'd go with key/value storage: https://developer.apple.com/library/mac/documentation/General/Conceptual/iCloudDesignGuide/Chapters/DesigningForKey-ValueDataIniCloud.html
Another option you could choose is Apple's replacement for reading the UDID which is to grab the advertising identifier. However it is possible for users to block this in Settings and your app could theoretically be kicked out of the store if it's used for something other than the intended purpose. I don't think it's actively policed, but still probably not a good idea to use it.
A belts and suspenders option would be to do everything:
save it to disk (in application support)
save it to key value storage in icloud
save it to keychain
use the advertising identifier to and send it to a remote server that you control (personally I'd skip this to avoid having the app banned from the store)
However... I'm not sure if Apple allows users to be banned. You might well be violating the developer rules by doing so. Especially the last one, which goes something like "this list is incomplete and constantly changing, your app might cause us to add a new rule to the list".
If it's a paid app or has in app purchases I'm pretty sure they would issue refunds to any customer who complains, and they'd probably follow the refund up with kicking your app out of the store.
Were I tasked to implement something like this, I would do exactly what you suspect: generate a simple random token, keep it in the keychain, and include it in API requests.
Nothing in the iOS keychain is removed when the app is uninstalled. I don't actually know of a good way to manually remove stuff from it.

Access iOS contact list without permission or asking - Privacy matters

I do know how to ask permission for contact's list accessing, is a very simple implementation, also I know Apple checks all this in case of going live to the App Store.
I'm about to receive a AdHoc bundle to a third party client, very very picky with privacy issues and I want to be certain that you cannot in any possible way in iOS7 access to the the address book, without previous and clear authorisation, nor storing some file in local or sending it through a web-service.
If there's other sensitive information than a programmer can access without the operating system firewall please let me know as well.
I read some subroutines can go through...
QUESTION: Can a developer access to the addressbook or personal information, directly or indirectly using a third party API or subroutine to the personal data, without explicit permission? Is an AdHoc bundle as secure as an AppStore reviewed App in that case?
Please do not punish me with negative feedback if you are not interested in privacy issues or think was that obvious, actually Apple's documentation is not clear and is focused on AppStore, mostly.
Thanks!
This answer came up in every search I did trying to find, CNContactPickerViewController, so I figured I should respond for posterity.
In iOS 9 and later you can call CNContactPickerViewController to present a system controlled contact picker that doesn't require permission to access the user's contacts. You can't hoover up all their contacts, which is what the original question implied (and is super creepy), but at least you can prompt the user to select a contact (or multiple contacts), which is sufficient for many legitimate use-cases.
Docs
The Address Book cannot be accessed without permission. No third-party API can get in, because internally, these API's need to go through the same permission checks as you need to. No app can get into a user's address book without the user's permission.
This is because of a security issue that Path, and some other apps, uploaded its users' address books to their own servers to use for whatever reason. To read more about it, look here
After this surfaced, Apple required the user's permission to access the user's contacts. Apple's iOS platform is possibly the most secure operating systems today, and there are few security holes that exist in their API's (minus the goto fail; mess-up).
App Store reviewed apps are more secure for the user than Ad-Hoc apps. The developers at Apple make sure that you do not do anything malicious with the user's contacts. In Ad-Hoc apps, there is no checkup. So, if you wanted to do anything dirty with their contacts in an Ad-Hoc app, you technically could (if the user gives you permission at all). You do not need to state what you will be doing with the permission, and so you are able to take advantage of the user's trust in you.
If you want the company to trust the app, suggest that they look it over with their own reviewers. If they don't think you are doing anything fishy, you are good.

iPhone app consumables - Server vs keychain method

I had an iPhone app developed by a company, which contains consumables purchases, specifically a currency named as "coins", used for app-specific purchases. In the current version, the team has added the ability for a user to register under a username/email/password. This information is stored on my external server and used as a recovery for the user's purchased coins via signing in using these credentials.
The model looks fine programmatically but is not convenient in terms of usability. Ideally, i would want my users to not have to register at all. I have been reading that it is a possibility to store the user's purchased consumables on the client side, using the internal keychain.
Now this would imply that consumables can only be restored on this single device (i guess unless iCloud is used). But is this allowed by Apple ? Or there should be a method to restore across different devices ?
If the keychain method is allowed, I believe that it would be way better for my app to go with that. I just wanted to make sure that Apple would not have a problem with that. I have been reading that it's allowed, but do not want to have unpleasant surprised after changing the whole client-server model to client-only keychain.
If you have experience with that, could you please let me know what the case is ?
EDIT : Somewhere on SO I read that using Gamecenter's GKPlayer class is also a way to store information on my server and retrieve that automatically in order to identify a user purchase. This would mean that the step of username/email registration is avoided, which is something i really really want to avoid. Is this really a possibility that is allowed by Apple ?
EDIT 2 : I am now thinking that I will keep the client-server model but lose the username/password and use the device id instead. This way i will be able to keep the restoration of coins working on a specific device. Would that be ok you think?

Saving information about previous purchased items in iOS

I am working on an app that has a number of in app store purchase items that will enable certain functionality.
After each item is purchased, I would need to remember it (of course). I would also like to persist this information in iCloud in case the app is deleted or is installed on another device.
What is the best data structure to be used?
Can user defaults database be used for this?
What is important is that the user will not have access to change those values and enable by themselves the paid functionality.
Can user defaults database be used for this?
It can, but it's not the best idea to do so, since
What is important is that the user will not have access to change those values and enable by themselves the paid functionality.
and NSUserDefaults stores its contents as binary or plaintext property lists. Easily changeable on a jailbroken device. (Also changeable on a non-jailbroken one by modifying the iTunes backup files).
What you could do is either store them in the keychain, although the keychain is not really designed for this (and it can also be dumped on a jailbroken device using Ptoomey3's awesome Kaychain-Dumper tool), or better store it remotely on your server and let your server check what the user has purchased.
Of course, if it's not only the server that does the check, so for example you don't only send or don't send content based on purchases, but you also use this check for performing actions within your app, then it also can be hacked (google "MobileSubstrate cheat DoodleJump" for a nice example).
All in all: there's no perfectly secure system.
I use the KeychainItemWrapper class to store a flag in the keychain. The nice thing is, so far, is that the keychain survives an app deletion. IF the user then reinstalls the same app on the same device, the keychain data is still there.
There is no need to use iCloud. If the user installs your app on another device, you just need to provide a "Restore Purchases" button in your app. Then you call the Store Kit APIs to restore existing purchases. The "In-App Purchasing Programming Guide" covers how to do this.
This same functionality will allow a user to restore their purchases even if the flags in the keychain are lost.

Resources