Connecting iPhone app to a secure RESTful API? - iphone

I am building a RESTful API in Python with the Pylons framework, serving it with Apache2 and mod_wsgi, and would like to connect it to an iPhone app. I have very little experience with HTTPS, SSL, and certificate authorities, and I am wondering how I would go about securing my API.
How do I make sure that the API is being served through HTTPS? Is it necessary to, as in this example, set up an SSL certificate? If I sign an SSL certificate through an authority not recognized by iOS (CACert.org, for example, and mainly because it is free), will that affect my app's ability to communicate with my server? How have others solved this problem of securing communications between a web-based RESTful API and iPhone apps?
Also, how does OAuth fit into all this?

This really depends on what you mean by "securing" your API.
Do you mean that you want to A) secure it so that unauthorized people are unable to access the API or B) do you mean that you want some level of encryption on the data passed back and forth between the client and server?
If the answer is B or both, then you will definitely need to look at getting an SSL certificate and installing it on the server. Most certificate authorities have guides on how to do this.
I'm not sure what you mean by "an authority not recognized by iOS" but you should still probably consider forking out the dough for a certificate from a recognized authority. It still wouldn't hurt to try CACert.org though if they are offering free certificates. I can't really see there being any problem in terms of the ability of communication between server and client being affected.
In terms of securing your API from unauthorized clients, you could check out OAuth (see http://oauth.net/). There are various Python libraries for OAuth. Check out https://github.com/simplegeo/python-oauth2 for example. The only thing you may want to consider is that there is a reasonable learning curve when it comes to implementing OAuth.
The second link above demonstrates a simple OAuth client and also has example code for a three-legged authentication process.

You can handle certificates programmatically in iOS. You can even use self-signed certificates as long as your code acknowledges the fingerprint. I can't remember the details off the top of my head, but I know you can use didReceiveAuthenticationChallenge to do this.
In the long run, it is simpler to just buy a cert (cacert.org won't do).

Related

Mobile app/API security: will a hardcoded access key suffice?

I'm building a mobile app which allows users to find stores and discounts near their location. The mobile app gets that information from the server via a REST API, and I obviously want to protect that API.
Would it be enough to hardcode an access key (128 bit) into the mobile app, and send it on every request (enforcing https), and then check if it matches the server key? I am aware of JWT, but I believe using it or other token-based approach will give me more flexibility but not necessarily more security.
As far as I can see the only problem with this approach is that I become vulnerable to a malicious developer on our team. Would there be a way to solve this?
First, as discussed many times here, what you want to achieve is not technically possible in a way that could be called secure. You can't authenticate the client, you can only authenticate people. The reason is that anything you put into a client will be fully available to people using it, so they can reproduce any request it makes.
Anything below is just a thought experiment.
Your approach of adding a static key, and sending it with every request is a very naive attempt. As an attacker, it would be enough for me to inspect one single request created by your app and then I would have the key to make any other request.
A very slightly better approach would be to store a key in your app and sign requests with it (instead of sending the actual key), like for example to create a hmac of the request with the key and add that as an additional request header. That's better, because I would have to disassemble the app to get the key - more work which could deter me, but very much possible.
As a next step, that secret key could be generated upon the first use of your app, and there we are getting close to as good as this could get. Your user installs the app, you generate a key, store it in the appropriate keystore of your platform, and register it with the user. From then on, on your backend you require every request to be signed (eg. the hmac method above) with the key associated with your user. The obvious problem is how you would assign keys - and such a key would still authenticate a user, and not his device or client, but at least from a proper keystore on a mobile platform, it would not be straightforward to get the key without rooting/jailbraking.But nothing would keep an attacker from installing the app on a rooted device or an emulator.
So the bottomline is, you can't prevent people from accessing your api with a different client. However, in the vast majority of cases they wouldn't want to anyway. If you really want to protect it, it should not be public, and a mobile app is not an appropriate platform.
YOUR PROBLEM
Would it be enough to hardcode an access key (128 bit) into the mobile app, and send it on every request (enforcing https), and then check if it matches the server key?
Well no, because every secret you hide in a mobile app, is not anymore a secret, because will be accessible to everyone that wants to spend some time to reverse engineer your mobile app or to perform a MitM attack against it in a device he controls.
On the article How to Extract an API key from a Mobile App by Static Binary Analysis I show how easy is to extract a secret from the binary, but I also show a good approach to hide it, that makes it hard to reverse engineer:
It's time to look for a more advanced technique to hide the API key in a way that will be very hard to reverse engineer from the APK, and for this we will make use of native C++ code to store the API key, by leveraging the JNI interface which uses NDK under the hood.
While the secret may be hard to reverse engineer it will be easy to extract with a MitM attack, and that is what I talk about in the article Steal that API key with a MitM Attack:
So, in this article you will learn how to setup and run a MitM attack to intercept https traffic in a mobile device under your control, so that you can steal the API key. Finally, you will see at a high level how MitM attacks can be mitigated.
If you read the article you will learn how an attacker will be able to extract any secret you transmit over https to your API server, therefore a malicious developer in your team will not be your only concern.
You can go and learn how to implement certificate pinning to protect your https connection to the API server, and I also have wrote an article on it, entitled Securing Https with Certificate Pinning on Android:
In this article you have learned that certificate pinning is the act of associating a domain name with their expected X.509 certificate, and that this is necessary to protect trust based assumptions in the certificate chain. Mistakenly issued or compromised certificates are a threat, and it is also necessary to protect the mobile app against their use in hostile environments like public wifis, or against DNS Hijacking attacks.
Finally you learned how to prevent MitM attacks with the implementation of certificate pinning in an Android app that makes use of a network security config file for modern Android devices, and later by using TrustKit package which supports certificate pinning for both modern and old devices.
Sorry but I need to inform you that certificate pinning can be bypassed in a device the attacker controls, and I show how it can be done in the article entitled Bypass Certificate Pinning:
In this article you will learn how to repackage a mobile app in order to make it trust custom ssl certificates. This will allow us to bypass certificate pinning.
Despite certificate pinning can be bypassed it is important to always use it to secure the connection between your mobile app and API server.
So and now what, am I doomed to fail in defending my API server... Hope still exists, keep reading!
DEFENDING THE API SERVER
The mobile app gets that information from the server via a REST API, and I obviously want to protect that API.
Protecting an API server for a mobile app is possible, and it can be done by using the Mobile App Attestation concept.
Before I go in detail to explain the Mobile App Attestation concept is important to we first clarify an usual misconception among developers, the difference between the WHO and the WHAT is accessing your API server.
The Difference Between WHO and WHAT is Accessing the API Server
To better understand the differences between the WHO and the WHAT are accessing an API server, let’s use this picture:
The Intended Communication Channel represents the mobile app being used as you expected, by a legit user without any malicious intentions, using an untampered version of the mobile app, and communicating directly with the API server without being man in the middle attacked.
The actual channel may represent several different scenarios, like a legit user with malicious intentions that may be using a repackaged version of the mobile app, a hacker using the genuine version of the mobile app, while man in the middle attacking it, to understand how the communication between the mobile app and the API server is being done in order to be able to automate attacks against your API. Many other scenarios are possible, but we will not enumerate each one here.
I hope that by now you may already have a clue why the WHO and the WHAT are not the same, but if not it will become clear in a moment.
The WHO is the user of the mobile app that we can authenticate, authorize and identify in several ways, like using OpenID Connect or OAUTH2 flows.
OAUTH
Generally, OAuth provides to clients a "secure delegated access" to server resources on behalf of a resource owner. It specifies a process for resource owners to authorize third-party access to their server resources without sharing their credentials. Designed specifically to work with Hypertext Transfer Protocol (HTTP), OAuth essentially allows access tokens to be issued to third-party clients by an authorization server, with the approval of the resource owner. The third party then uses the access token to access the protected resources hosted by the resource server.
OpenID Connect
OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It allows Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.
While user authentication may let the API server know WHO is using the API, it cannot guarantee that the requests have originated from WHAT you expect, the original version of the mobile app.
Now we need a way to identify WHAT is calling the API server, and here things become more tricky than most developers may think. The WHAT is the thing making the request to the API server. Is it really a genuine instance of the mobile app, or is a bot, an automated script or an attacker manually poking around with the API server, using a tool like Postman?
For your surprise you may end up discovering that It can be one of the legit users using a repackaged version of the mobile app or an automated script that is trying to gamify and take advantage of the service provided by the application.
Well, to identify the WHAT, developers tend to resort to an API key that usually they hard-code in the code of their mobile app. Some developers go the extra mile and compute the key at run-time in the mobile app, thus it becomes a runtime secret as opposed to the former approach when a static secret is embedded in the code.
The above write-up was extracted from an article I wrote, entitled WHY DOES YOUR MOBILE APP NEED AN API KEY?, and that you can read in full here, that is the first article in a series of articles about API keys.
Mobile App Attestation
The role of a Mobile App Attestation solution is to guarantee at run-time that your mobile app was not tampered with, is not running in a rooted device, not being instrumented by a framework like xPosed or Frida, not being MitM attacked, and this is achieved by running an SDK in the background. The service running in the cloud will challenge the app, and based on the responses it will attest the integrity of the mobile app and device is running on, thus the SDK will never be responsible for any decisions.
Frida
Inject your own scripts into black box processes. Hook any function, spy on crypto APIs or trace private application code, no source code needed. Edit, hit save, and instantly see the results. All without compilation steps or program restarts.
xPosed
Xposed is a framework for modules that can change the behavior of the system and apps without touching any APKs. That's great because it means that modules can work for different versions and even ROMs without any changes (as long as the original code was not changed too much). It's also easy to undo.
MiTM Proxy
An interactive TLS-capable intercepting HTTP proxy for penetration testers and software developers.
On successful attestation of the mobile app integrity a short time lived JWT token is issued and signed with a secret that only the API server and the Mobile App Attestation service in the cloud are aware. In the case of failure on the mobile app attestation the JWT token is signed with a secret that the API server does not know.
Now the App must sent with every API call the JWT token in the headers of the request. This will allow the API server to only serve requests when it can verify the signature and expiration time in the JWT token and refuse them when it fails the verification.
Once the secret used by the Mobile App Attestation service is not known by the mobile app, is not possible to reverse engineer it at run-time even when the App is tampered, running in a rooted device or communicating over a connection that is being the target of a Man in the Middle Attack.
The Mobile App Attestation service already exists as a SAAS solution at Approov(I work here) that provides SDKs for several platforms, including iOS, Android, React Native and others. The integration will also need a small check in the API server code to verify the JWT token issued by the cloud service. This check is necessary for the API server to be able to decide what requests to serve and what ones to deny.
SUMMARY
In the end, the solution to use in order to protect your API server must be chosen in accordance with the value of what you are trying to protect and the legal requirements for that type of data, like the GDPR regulations in Europe.
DO YOU WANT TO GO THE EXTRA MILE?
OWASP Mobile Security Project - Top 10 risks
The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.

Facebook Canvas App developing without SSL

Facebook recently changed the security settings on Account Configs, now there is no more an option to force, or not, an application to use HTTPS protocol.
Therefore, it isn't possible to do a App without a SSL key. Previously we could just don't fill Secure Canvas URL field, and access the canvas app through the HTTP protocol. But now, without the option in the security user config, the facebook app keeps redirecting to the HTTPS protocol.
So, there is some workaround for this ?
As CBroe says, you need SSL.
There are 2 things you need in my opinion:
A webserver with SSL.
IF you're in OSX and you run Apache, this tutorial really helps:
http://blog.andyhunt.info/2011/11/26/apache-ssl-on-max-osx-lion-10-7/, plus you might want to add your certificate as a trusted (root?) certificate, or certificate authority. (I'm not very well versed in this)
The only caveat I found, specially for Chrome, is that when you're generating the Certificate Request File, under Common Name place "localhost" or the host you're using for development. This last caveat should be similar in Windows, since it's a browser requirement that the certificate common name matches the actual host. Browsers like Firefox allows you to permanently trust a certificate, thus avoiding all the certificate installation on the OS and trusting.
A proxy app
proxy-like app to act as a man in the middle and decode the encrypted information, in order to see the actual requests and response being sent and received from the server. There should be other software, but the one I use and love is Charles Proxy, which can do this and tons more.
Hope it helps!

Advice on implementing web server security in iPhone app

I have a relatively successful app in the app store that allows people to view metrics on their iDevice using a JSON file hosted on the their server. The app has a simple settings screen in which you simply type the URL of your JSON file and the app takes care of visualising the data in the file. I use AFNetworking for this.
For example the URL might be: http://www.mylargecompany.com/factorykpi.json
Customers are now coming back to me and asking for the ability to connect to their servers more securely. Problem is there is a myriad of ways you can secure your server.
I need some advice. What kind of standard security features would I need to build into my app. I am confused by OAuth, HTTPS, etc.
I believe OAuth would mean the customers server would have to use it? Can you make a generic OAuth login screen in an app or do you need to know which web server you are connecting to authenticate.
Any advice on even the most basic of security measure would be very welcome!
Regards,
MonkeyBusiness
Security is really a very broad topic. There is no short answer. In any case, both web service and client app need to implement security mechanisms. I would recommend, you provide both the web service and client app.
You likely need some user login with a password, "server verifies user identity" and "client verifies server identity" using certificates. Then you utilize HTTPS which ensures to transport confident data in a secure way. The web service should be implemented with one of the well known web application frameworks since security is a scary business, and tricky. Implementing everything yourself, might end in a suboptimal insecure application.
You should now read more about the complex topic and come back when you have specific questions.
... most basic would be to use https, which would secure the transaction, but anybody accessing the same link would be able to access the same data. Thus you will need some kind of authentication, starting with a simple secret key passed as POST request, username and password and/or via certificates.

Secure iPhone (iOS) /server communication

I'm building and iPhone App that will make requests to an application of mine running on a server. I'm using REST to build the server's application API. What is the best way for securing the requests from the iPhone to the server and viceversa. Is OAuth a good option? What would you recommend?
Thanks!
If it's a server you control, use a SSL/TLS connection for all communications between the phone and your server. Make sure that the phone app code checks the server's certificate (e.g., to check that it is a cert for your domain name, where your domain name is hardcoded into the source code). This will protect against eavesdropping, man-in-the-middle attacks, message forgery, and other attacks on the data while it is in transit.
There is not really any way to answer the question "what's best" without a lot more information on the security needs of your app.
In general, you should consider authentication, authorization, and transport.
Authentication could be as simple as username/password login. This could be simple authentication, OAuth, kerberos, etc. It is meant to identify the user. Authorization deals with which services are allowed to be accessed by which groups or individuals. You'd need a way to grant and maintain privileges. Finally, securing the transport typically means using encrypted services, such as HTTPS over SSL. This prevent data from being intercepted or altered during transport.
There are many other considerations to think about including how your protecting personally-identifiable information, encryption, etc., but again, there is no one-size-fits-all solution that could be recommended.

How can I verify the authenticity of requests from an iphone app to my web service

I'd like to make requests from an iphone app to a web service I've built. How can I verify that requests made to the web service come from my iphone app (or indeed any authorised source) and are not forged?
I have looked at basic auth over HTTPS but is baking credentials into an application secure?
This question isn't really iphone specific; I'd like to know how to protect and authenticate requests in general.
Authentication can be asserted by presenting something you know, something you have, something you are or a combination of the three.
The iPhone doesn't have retinal or fingerprint scanners, so there are no "something you are" options available.
Client certificates work well as a "something you have" token. Most smartcards work by signing a message with an embedded certificate. When a certificate is compromised, it can be put onto a Certificate Revocation List (CRL) referenced by the webservers. Obviously, you wouldn't want to put your app's embedded certificate in the CRL -- that would deny access to all your users. Instead, you'll want users to download individual certificates to their iPhone.
After that, it's a matter of monitoring for unusual behavior to find the bad actors and adding those certs to the CRL. Two dead giveaways would be clients who send too many requests at once or from too many different IPs in too short a time.
Login/password is a simple "something you know" token. Like certificates, login/password combinations can be compromised and similar monitoring can be set up to find inappropriate behavior. The difference is compromised accounts would be marked "blocked" rather than added to a CRL.
By requiring both a client certificate and a login/password you increase the amount of effort needed to compromise an account.
Of course, you must ensure only valid accounts are added to the database. If there is an automated way to create new accounts and corresponding client certificates, then that account creation server/process becomes the easiest way for bad actors to create viable, unauthorized accounts. Requiring a real person to sign-off on accounts removes the automation process, but means a disgruntled or corrupt employee could create invalid accounts. Requiring a second person to counter-sign the account makes it harder for a single person to be an inside threat.
In short, ensuring high integrity of the clients is a process that can be made arbitrarily complex and expensive. What tools and processes you decide to deploy as the authentication scheme has to be balanced by the value of what it is protecting.
In theory, if you want the connection to be secure, the best is to have the client sign their request using a certificate. There are multiple resources about this. Look for "client certificate" on Google.
This example from Sun is in Java, but the concept is similar whatever the language.
PS: obviously, this doesn't prevent you from using other authentication methods such as passwords, etc...
PPS: Keep in mind that if someone manages to extract the certificate from your application, you are screwed either way ;-). You can imagine a store providing an individual certificate to each app and invalidating the certificates that are compromised.