Avoid the files inside my iOS app to be easily replaceable - ios

My app is an In-house app distributed via MobileIron. It uses Realm for the database, and also SDWebImage for image caching.
I made some tests, with iExplorer today, and I could see that the files are easily replaceable with this tool. This allows me to update the datas how I want, then replace the file on the iPhone, and it's done.
Anyway, it's not the case with the App Store Apps (files are not accessible via iExplorer).
I know I should may be use encryption for the Realm database, but it's more a general problem in this case.
How can I make sure that the files are not manipulated inside my app ?

Once applications are wrapped with the MobileIron AppConnect wrapper they become integrated into the secure container on the device. Each app becomes a secure container whose data is encrypted, protected from unauthorized access, and removable.
This url will give you more details.

Related

Is it possible to take all backed up data without jailbreak from iCloud (public,shared,private) by any app/tool, provided with iCloud credentials?

I am trying to build a mobile monitoring tool/app for iOS without Jailbreak. The only possible way to perfectly access all installed app's content is through iCloudKit.
Also I found Apple's MDM come a little close to this for BYOD devices but yet accessing individual application's data is not possible.
During all this process, I came across some website fonemonitor and phonemonitor (with and without) who claim to do the same without Jail Break.
So here is my question is it possible to take any application's data if we get access to the users iCloud account? Also, are all public, private and shared data accessible via iCloudKit? As the documentation clearly states private data is untouched.
How does app monitoring work for any iOS Devices through these websites. Any lead would actually help!

How to store critically sensitive information such as secret, key, token, encryptionKey in iOS application

When we talk about securing iOS application we often forget to secure most critically sensitive information such as secret, key, token, encryptionKey. This information is stored in iOS binary. So none of your server side security protocol will help you.
There are lots of suggestion that we should not store such information in the app but store in the server and get it via SSL secured web service call. But this is not possible for all application. E.g. if my application does not need web service at all.
In iOS app we have following option to store information.
UserDefault: Not appropriate for this case
String Constant: Not appropriate for this case. Can be reverse
engineer to retrieve or just use strings command
Secure Database: Store in Secure and encrypted Database. But again have responsibility to secure database username and password.
KeyChain: Best to store critical info. But we cannot save information before installing the app. To store in the keychain, we first need to open the app, read from some source and store in the keychain. Not appropriate for our case either.
Custom Hash String Constant: Not to directly use secret, token, key from service provider (mixpanel, paypal), instead use hash version of that information from custom key. This is also not perfect solution. But add complexity during hacking.
Kindly send some awsome solution to this problem.
If you don't want to use your own backend then use Apple. You can configure On Demand Resources and keep data file with your key, token, any secret on Apple server. After first download you can write this data to Keychain which is secure enough. I'm guessing networking between iOS and Apple server is also secure enough.
On-Demand Resources Essentials
Accessing and Downloading On-Demand Resources
1) Internet Connection Required
1.1) Push Notifications
Great way to have a secure data exchange could be to use (silent) push services from Apple, those use the apns and send data through https - more Details 3.1
1.2)
A more or less similar approach is also used when distributing new user certificates to already deployed applications, if a reinstall of the application is no opportunity AND the application requires a working internet connection anyway.
Downside: working network connection required and basically the information is coming to the application, when it is already being executed => seems not to be appropriate for your case. (see step 4)
2) Static data (as there will be no exchange without network connection / communication partner)
Encryption of data with private key being provided in the bundle itself. Whether it is now a string or a hash, which can be reverse engineered with functions you got emebedded in your application.
Since iOS9 it is pretty hard to decompile iOS applications and basically you will mainly have a look into the provided header-files. So if you had such a function, string, hash value or whatever, make sure you got it in your .m-file!
But again: if the information is not device or user specific, just a secret across your own micro environment, valid across all devices, you would have to provide the encrypted data AND the decryption method in the same bundle, if there is no update process / information exchange or something else, you can think of.
Good for encryption:
iOS System.Security https://developer.apple.com/reference/security
or simply openssl
The difference between your described keychain approach is:
You got a value, which WILL be encrypted and stored securely.
(2) describes the approach to have an encrypted and stored (in bundle) semi secure value, which WILL be decrypted
3) Information exchange
You describe critical data, which was hashed by another instance. Great! - Make sure, relly make sure, the instance you are talking to is really the instance you expect to be (Network Hooking prevention with ssl certificate pinning etc, but even here you might have intruder (men-in-the-middle)). And you will (probably) have a certificate being provided in your application bundle, to ensure the authenticity of the communication server - here you go again, data that is supposed to ensure a secure process between certain instances of your micro environment. Nevertheless, this data is being provided in your application's bundle.
3.1 Secure Information Exchange extended - Silent Push
Make use of Apple's servers to exchange your secrets for this purpose. If you just need to exchange small data chunks. I would recommend to use silent push notifications to the user, those do even work without explicit permission from the user. Huge advantage: In case your secrets or keys change, you can inform users as soon as possible about the change. They will likely only need the change, when they receive new data, which should reliably work in most cases. Exception: Data exchange in local networks or via bluetooth, in this case I would recommend to provide a notification to the user to have the requirement to update a local decryption key. Or exchange the key in this format as well. Once again: I am leaking some detailed information about your environment architecture.
Downside: You don't know, whether a user just used your app for the first time, until the user "tells" you so.
https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/APNSOverview.html#//apple_ref/doc/uid/TP40008194-CH8-SW1
3.1 Secure Information Exchange extended - In App Purchase
Use a frree In-App Purchase for the user to get the data to your phone. Good point here: you can provide larger data chunks easily, as this should be an active request by the user, the user does expect certain processing time and should also be aware of the fact to require a working internet connection.
Downside: User would have to select this on purpose. Up until then the app would not work accordinly.
https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Introduction.html#//apple_ref/doc/uid/TP40008267
So, it just slightly differs from the approach (2) in its basic idea.
In short: Can you provide additional information, what kind of data you need to encrypt/want to store securely and whether you will have a network exchange or not?
Would need some more information here :-)
I would like to emphasize once again that an application on iOS is not that easy to decrypt anymore, even decompiling would not get everything, you expect it to get. For instance decryption tools like dumpdecrypt were only working properly up until iOS 8.4
It seems to me that the best way to do this is using the built in CloudKit. You can save your secrets in the CloudKit Dashboard and then fetch them on startup. Since CloudKit is only a transport layer you'll have to store the app secrets in the KeyChain.
I know you mentioned the KeyChain not being ideal for your use case (not sure why), but this is a good way of not including the secrets in your app. You can't get around fetching your app secrets from another source.
CloudKit access is secured using the system iCloud account and if there is no iCloud account you still access the iCloud servers securely. Another added benefit of this is that you can change your app secrets at any time, so if you want to be even more secure you can implement a rotation schedule.
Learn more about CloudKit
Cocoapods-keys might be a best option.
From cocoapods-keys doc's
Key names are stored in ~/.cocoapods/keys/ and key values in the OS X
keychain. When you run pod install or pod update, an Objective-C class
is created with scrambled versions of the keys, making it difficult to
just dump the contents of the decrypted binary and extract the keys.
At runtime, the keys are unscrambled for use in your app.
The generated Objective-C classes are stored in the Pods/CocoaPodsKeys
directory, so if you're checking in your Pods folder, just add
Pods/CocoaPodsKeys to your .gitignore file. CocoaPods-Keys supports
integration in Swift or Objective-C projects.
Check out this link for installation, usage and more info : https://github.com/orta/cocoapods-keys
I agree with #Lobsterman and believe that the best way will be to use a combination of these.
Don't include the secret information in the app initially.
Deliver the secret key either as in-App purchase content ,on-demand resource or send it through push notification. This will add the benefit of changing the key periodically if you want and the change will take effect without any additional effort.
Add the entry to keychain access once the content is delivered.
If the data is extremely sensitive then it should never be stored offline on device because all devices are crackable. If you still want to store on device then keychain is one option for storing data securely, However it's encryption is based on the pin code of the device. User's are not forced to set a pin, so in some situations the data may not even be encrypted. In addition the users pin code may be easily hacked.
A better solution is to use something like SQLCipher which is a fully encrypted SQLite database. The encryption key can be enforced by the application and separate from the user's pin code.

Is it possible to add external data to CloudKit?

I'm writing an iOS app that uses data collected from websites. A large amount of data is retrieved when parsing the content so it needs to come from a backend server where data can be collected and added to the database once rather than parsed on the device.
I've looked at BaaS frameworks like Parse and am considering using this, but I'd like to know if it is possible to add records to CloudKit externally from say a Linux server? I've looked everywhere and can't find anything other than adding records programmatically (from the app) or via the dashboard.
You could create an OSX app (no other platforms are supported yet) that is communicating to the same CloudKit container. But then that app also needs to be signed and submitted to the app store. You don't have to make it public, you just need to submit it.

Apps that read or write data outside its designated container area will be rejected

I am developing an app that sends data from the app to an sql server. I have read in the App Store guidelines (point 2.6) that "Apps that read or write data outside its designated container area will be rejected". Does that mean I will not be able to do this?
I'm pretty sure they're just referring to the designated "sandbox" each app is assigned to. Each app has their own documents directory to save local files, and I believe they're just warning you not to attempt to write outside of this (if you were even able to on non-jailbroken devs). They also don't want you attempting to access other apps that you don't have permission to access.
I've had several apps go to the store that write to and read from Google App Engine servers and they've been accepted with no problem. So I think you'll be good to go saving data to your own server.

Opening and storing encrypted documents offline in iOS

I have encrypted files downloaded and available for offline view in a folder, I would like to know:
how to open them in the appropriate reader as these are ms office docs and prezi format
I suppose they will have to be unencrypted so that reader can read them but in this case how to ensure security?
which folder to use to avoid iCloud sync, I already read this Disable iCloud sync
Does iOS protects documents of the application by encryption based on app key as I read it or am I wrong?
Speaking extemporaneously, as thoughts occur, Sven is right about UIDocumentInteractionController and that objects are identified by URL.
However, it's possible you don't need to unencrypt your files on disk for this to work. You can probably write your own little URL protocol (subclass NSURLProtocol and implement methods appropriately; you should end up checking that URLs are within the invented scheme you've created — e.g. myApplicationEncrypted:// — then posting data packets to a NSURLProtocolClient) and register it with the device via NSURLProtocol +registerClass.
You'll obviously need to decrypt between disk and protocol client. So you'll be passing unencrypted data on — you'll need to make a trust judgment on UIDocumentInteractionController.
The document interaction controller is documented to work within your app, so there shouldn't be sandbox concerns.
You can send your documents to other apps using an UIDocumentInteractionController object. You initialize it with a file URL pointing to your document and then use one of it’s methods to present it.
This takes care of displaying a preview (if possible) and letting the user select the application the document should be opened in.
The document has to be decrypted for this to work. You then cannot make any guarantees about the security of your file - once it is handed over to another application it is out of your control.
If your app doesn’t explicitly opt-in to use iCloud sync your data will not be synced with iCloud. What will be sent to iCloud are backups of the whole device though (if enabled). There are ways to disable this for single files as you already read in the question you linked.
The iOS file protection is based on a device key, not on a per app key. This also is not necessary because apps are protected from each other by the sandbox, unless your phone is jailbroken. On a jailbroken phone there are no security guarantees.

Resources