What are the best practices to add sensitive data to the iOS application?
For sensitive data I mean a key or token to communicate with some external server.
Can we compile a certificate in the app, and iOS can remove it on installation?
I feel like we can not really 100% guarantee security of it, but what is the best practice layer we can add.
There is no mechanism that will ensure to a server that only your application is allowed to speak to it. So if that is your goal, then it is unsolvable. This has been talked to death on SO. Just a few:
Secure Communication Between iPhone and Server?
Store an encryption key in Keychain while application installation process
Secure https encryption for iPhone app to webpage
(And the many other links within those postings.)
And elsewhere:
Obfuscating Cocoa
You cannot authenticate devices or software. You can only authenticate users. That means a login. Without a login that is partially stored in the user's brain (or at least in something separate from their iPhone), it's just obfuscation.
Now, that doesn't mean that obfuscation is useless. It isn't. You can get some mileage out of a simple authentication token (like a client key), but don't expect it to survive an attack. That doesn't mean you shouldn't do it; it just means you shouldn't spend a lot of time/money on it since it will fail pretty fast.
In no cases should you implement something that ticks off paying customers. Read the several threads linked above (and the several threads linked from those threads). If after that, you still absolutely need a solution, then you'll need to hire someone to keep track of the cracks and fix them every time a new one comes out. It will never stop.
Related
As we heard this year's WWDC, at the end of 2016, Apple will make ATS mandatory for all developers who hope to submit their apps to the App Store. http://9to5mac.com/2016/06/15/ats-https-ios-apps/
http://www.cso.com.au/article/577197/apple-tells-ios-9-developers-use-https-exclusively/
It is understandable in cases where privacy, encryption (...) is a factor. But what about simple (news...) feeds, API-s whare it is not the case?
What about simple json or rss feeds? E.g. I have a very simple public json feed that can be called without any authorization, will it also need https? And what about simple RSS feeds? Huge majority of them communicates now via http. What about downloading image files from the web in an app?
Thanks in advance!
This is very rapidly becoming "the new normal." (Did you notice that even WikiPedia now uses https connections to their site?) Non-encrypted communications can be effortlessly intercepted, e.g. in the coffee shops and public places where so many people routinely find themselves. The problem is even more severe now that "free public WiFi" is available in "ordinary" stores and Wal-Marts, and people have their phones set to automatically connect to any of them. (People do not realize how insecure they are! But, they're learning ...)
The most appropriate solution, then, is to "encrypt everything." And so, this is what Apple is now mandating.
Yes, even "routine" communications, news-feeds and such. All of the traffic that passes through the airwaves will be encrypted.
Remember, also, that these techniques not only secure the communication, but are capable of identifying the sender and the receiver to one another through mutually-held certificates. (Web sites don't always use client-identification, although they can, and apps definitely should.) This, if used properly, will close a very big headache-hole for servers, because they now will know just who they are talking to. Client software can trust that they are talking to the right server, and that their communications are "received as tendered."
"Android or iOS or Windows or what-have-you," you should be doing this. Every mobile device implements SSL and possibly other encryption stacks. Do not send anything over air-waves "in the clear."
A "simple feed", in some country, can kill you. Protect your users, encrypt everything.
Okay, this question applies to most scenarios where a vendor distributes an SDK binary to 3rd party developers to use. But for easier discussion, let's assume I am developing an iOS SDK in Objective-C, and planning to hand it to any developers who have registered on our portal.
This SDK will access our services located on our server. And since the resources on our server are limited (well, on any server actually), we have built in some simple throttling mechanism in the SDK to prevent bad use of API's, like putting a remote procedure calls in a loop which executes 10K times a second, whether purposefully or not. Anytime such a thing happens, we throw.
As long as the developers use the binary as is, things are fine. But what if someone tries to do some funny things, like breaking our throttling mechanism by changing the binary, then linking to their app? In such a case, our client throttling mechanism no longer works, and a few instances of their app running could bring our server down.
Our thought is that we can build some checksum validation mechanism in the SDK binary, then calculate the binary's checksum during runtime initialisation, and compare that to the one in the binary. If our binary is tampered with, we cancel the initialisation, and prevent the host app from using our resources.
We already have server-side throttling mechanism on the server. But we also throttle on the client, since many unthrottled requests to the server still consume resources unnecessarily on the server, even we have throttling ready on the sever.
Is that a viable thought? Anyone have experience on this matter?
Thanks!
I've noticed several tutorials for most of the major players in social networks have examples where a API key tied to your account is embedded (usually in plan text) in the source code. For example, Google Maps APIs Premium Plan. This key is used to bill your company.
I found a similar question in Is it safe to put private API keys in your .m files when exporting to the appstore?1 - Of note, anyone with a jailbroken phone can see the unencrypted executable.
Is this practice actually safe, and if so, why?
Embedding API keys in an app is not secure and generally not a good practice but does require a substantial work factor to obtain them, it is not trivial. There is no tool to decrypt the executable other than the OS for execution.
RE: "anyone with a jailbroken phone can see the unencrypted executable." is not really true. Just jailbreaking will not decrypt the app binary, it is only decrypted as the binary is loaded in RAM to execute and the key will not be available, it is decrypted in hardware in the DMA path. One needs to add debugging tools and catch the binary after it is loaded into memory for execution.
You need to determine who the attacker is, how much skill and time the attacker will spend and the cost to you.
There is no 100% secure solution, only increasing the work factor.
An alternative is to obtain the API keys on first run at login to a server and then move them to the Keychain. But this is also just an increase in work factor because as above the executable can be examined at run time when it is sent to the service.
As long as the key has to be in the app memory during any part of execution it is vulnerable.
Putting the API keys in the source may meet the security needs.
After reading this article on Ars Technica I started looking for a way to enable an encrypted, yet passwordless public network. It is probably not possible due to specifications which require a certain number of characters and OSs complying with them, but what about accepting any password?
It will most definitely require custom scripting or even modifying the sources, so I've chosen OpenWRT to try this out. The relevant sources can be found here and here, which are used for building the wpad, hostpad and wpa-supplicant packages. By default OpenWRT uses wpad-mini (suffix mini means an absence of the WPA Enterprise support).
One of my thoughts was to also try WPA Enterprise for this purpose. Would it be possible to write a simple script to mimic the Radius server response, being always positive, as if credentials were correct?
Another aspect of this question is security. If accepting any password was possible, wouldn't it mean that anyone could trick my device to connect to an AP with the same name, as say, I use at home, and have control over the traffic? This can be a very serious issue and it is better to talk about it publicly than just pretending that if we don't publish a way to do this, no one else will do the same on black markets or in governments.
upd: Would it be possible to use a simple captive portal to 'negotiate' encryption, ideally, without any user interaction apart of opening the page? Naturally, it won't be WPA. Here is a good list of captive portal solutions for OpenWRT. A precaution: with the current OS-level implementations this wouldn't prevent leaking unencrypted data before the negotiation happens. But since OSs already recognize captive portals and display notifications, it should be possible to add a security feature to prevent any data transfers before passing the captive portal.
I'm designing some OSX/iOS apps that I'd like to share a resource to be hosted on a webserver. I would like to have some sort of web app or script that can store a list of subscribers, and to notify them when the resource is updated. (The obvious goal here is to avoid having every app poll the webserver for updates.)
The only trick here is that I'd like a significant number of clients (say, a dozen) to be subscribed for updates on a 24/7 basis. I'm not sure if it's a good idea for all of the clients to maintain a live connection... I imagine that many web service providers will be happy about their webserver maintaining a dozen persistent connections (especially if they're virtually always idle).
(Edit) I looked into the Apple Push Network Service (APNs), but it's not the right solution for my problem. APNs requires an Entrust SSL Certificate, and some heavy interaction with the Apple Push Network service. My project is much simpler and more lightweight: I just need a script that says, "Upon receiving data from Device A, push it out to Devices B/C/D" (presuming those devices are somehow accessible... either through a persistent connection or some other technique).
What's the absolute simplest way of providing this mechanism?
The "simplest way" probably means different things to different people. If you're not a fan of locking yourself into third party services then there's a veritable plethora of app frameworks and open source tools you could use to build something yourself. But this is hardly 'simple' if web app development isn't your strong point.
There are several 'off the shelf' services available to do real-time messaging on iOS: bear in mind I'm just listing the ones I know from memory, there are other alternatives. Pusher and PubNub both offer real-time messaging services for mobile apps, along with ready to go SDKs. You can interface with them to send messages bi-directionally via sockets (so similar to how APNS works, but with considerable more control).
You could use these services with your own device/user management system, or you could use a 'backend as a service' provider such as Parse or Stackmob - you may not need this step, it depends how complex your intended app/integration is.
XMPPFramework has a publish–subscribe module (for XEP-0060) which works with most XMPP servers. I've even adapted it to work with Chat Server which comes with Snow Leopard.
If you already have an XMPP server this might be worth doing; otherwise it's kind of a heavyweight solution.