Secure API access with mobile apps in restricted environments - api

In our current project, IT rules prohibit anything that is not PROD to be publicly accessible from the Internet. Access to development and review environments must be severely restricted. That said, the project also includes mobile apps that are developed together with the cloud-hosted API layer.
In very general terms, what are the common approaches to securing DEV / REVIEW-stage APIs with mobile apps? We've come up with the following ideas:
IP whitelist on the ingress to the API (least secure, but easiest to use)
VPN gateway to the hosting environment, with corresponding DEV / test devices configuration
Mutual TLS authentication (most difficult to implement and operate)
There are multiple issues to address with each one of the approaches, but I'd like to understand the big picture before diving into any of that.

IP Whitelist
IP whitelist on the in the ingress to the API (least secure, but easiest to use)
I see it as least secure if you are whitelisting IPs that are not exclusive to your company office and/or the the IP is exclusive to your company but used by public WI-fis in your company.
Also in the case you need to whitelist access to remote developers and testers that may or not be in a public IP, this solution will be risky, because people always put convenience in front of security and they may ask to whitelist IPs that are from the coffee shop they like to work from, the shopping mall, the girl friend home, etc..
So I would discard this option, unless you are in a small office where you have the public WI-fi(the one for your clients to use) in a different IP from your main internet connection.
VPN Gateway
VPN gateway to the hosting environment, with corresponding DEV / test devices configuration
This approach seems to be the much wise to follow and only who have been granted access to the VPN will be able to use resources hidden behind it, and VPNs can be even used in public WI-fi.
Mutual TLS Authentication
Mutual TLS authentication (most difficult to implement and operate)
While is difficult to implement and operate they also suffer of the problem of certificate pinning be possible to bypass.
On this article about pinning in mobile apps we can read how easy it can be to implement certificate pinning:
// simplified android example
CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add("publicobject.com", "sha256/afwiKY3RxoMmLkuRW1l7QsPZTJPwDS2pdDROQjXw8ig=")
.add("bikewise.org", "sha256/x9SZw6TwIqfmvrLZ/kz1o0Ossjmn728BnBKpUFqGNVM=")
.build();
OkHttpClient client = OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.build();
In this same article we can also see how pinning can be a nightmare... as you said, difficult to operate!!!
The main difficulty with pinning is not technical but operational. By embedding fixed information about the server (the certificate) into the app you create a dependency between the two, as the term pinning implies. This means that whenever you (or your ops team) are planning to change the certificate on the server you must:
Generate the certificate in advance
Build, test and publish a new version of the app with both the new certificate and the old one.
Wait for most (80%, 90%, 99% ?) of your users to upgrade to the new version
Change the cert on the server
Build, test and publish a new version of the app with the old certificate removed.
As if this was not enough, certificate pinning can be by passed by using introspection frameworks, as pointed on the same article I linked above:
Even if you successfully navigate the operational difficulties inherent in implementing pinning, there is still the giant pink elephant in the room that is unpinning. The development of hooking frameworks such as Xposed has reached such a level of sophistication that a rich ecosystem of modules exists to target various aspects of Android apps including the pinning functionality of HTTP libraries. Using them is very straightforward.
Another Approach - Going the extra mile
That said, the project also includes mobile apps that are developed together with the cloud-hosted API layer.
In the context of a mobile apps you can use a technique devised as Mobile App Attestation, that can be used across all environments to protect the API server, for the mobile apps, from responding to requests that are not originated from the genuine mobile app binary you released, signed and registered for that specific environment.
Mobile App Attestation
The role of a Mobile App Attestation service is to guarantee at run-time that your mobile app was not tampered or is not running in a rooted device. It consists of a SDK integrated in a your mobile app that runs in the background, without impacting the user experience, and communicates with a service running in the cloud to attest the integrity of the mobile app and device is running on.
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.
The mobile app must send the JWT token in the headers of the request for very API call it makes. This allows 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.
Anyone trying to verify at run-time if a JWT token issued by the Mobile App Attestation is a valid or invalid one will not succeed, because the only difference between them is the secret used to sign it, and this secret is only known at anytime by the Mobile App Attestation service and the API server. This means that even the mobile app is not in possession of the secret, thus is not aware if is sending a valid or invalid JWT token to the API server.
Conclusion
From your 3 solutions I would go with VPN approach and if you would want to go for the extra mile you should consider implement your own Mobile App Attestation service to guarantee that mobile APIs for any environment only communicate with mobile apps for that specific environment/stage and deny requests from any other source. This solution even allows for your mobile API to be hosted on the public domain without risking leaking any data, thus not needing a VPN on front of it.

Related

Providing encryption and password for an IOT device over gRPC

I've been breaking my head over how to do this, as it doesn't seem to fit any example I could find online.
My IOT device servers will run on the client network and may be accessed over it or over the open internet (with port forwarding). the device comes with a paper-printed initial pass like a router.
the client is running a mobile app.
As I hate planned obsolescence (ie, the device should keep working even if the company shuts down), I don't want to create a dependence on any third-party auth service, so the server and the app should just establish trust between themselves.
with the initial contact assumed to be trusted.
In all the examples for gPRC auth I could find, the client should somehow have ahead of time the server public key. but as there are many devices, and I want each one to have a unique cert, I don't see how I can ship the app preloaded for the specific device the user will get.
I have come up with the following:
the device generates private/public key
an insecure grpc channel serves the public key to the client
the secure grpc channel is established with that key
the client authenticates with the initial password to use the API over the secure channel
client changes the password
I'm not looking for super-max security, just basic common-sense security.
the main issue I have with the typical scheme where SSL is used to authenticate vs a domain is that I don't know via what domain/address the device would be accessed.
are there any glaring problems in the scheme? or any reason it would not work?
Thanks!

How to prevent MITM attacks on API Key and API secret?

How would someone go about preventing MITM type attacks against API secrets/ API keys?
How does facebook/ instagram protect their users against MITM type hacks?
Do they even protect the users? Or they assume that any possible attacks should be shouldered by users?
Some Context on my Answer
I assume that your question is in the context of mobile apps, thus my answer will show how to protect against a MitM attack for APIs serving mobile apps and how it can be bypassed.
Your Facebook/Instagram Related Questions
How does facebook/ instagram protect their users against MITM type hacks?
Do they even protect the users? Or they assume that any possible attacks should be shouldered by users?
This questions are best answered by an insider at Facebook/Instagram or from a security researcher that have done extensive work on their mobile apps and APIs.
Sorry for not being able to elucidate you here.
Preventing MitM Attacks
How would someone go about preventing MITM type attacks against API secrets/ API keys?
This one I am able to help you with and the quick reply its by using certificate pinning against the certificate public key, and we will go in more detail below.
In a first instance you will want to secure the HTTPS communication channel by configuring the mobile app to only establish a connection with the API, during the TLS handshake, if it presents the certificate issued for its domain and that is known and trusted by the mobile app, ignoring any other that may still be valid as per validation against the certificate trust store of the device. I go into more detail about it and how to implement it on the article I wrote Securing HTTPS with Certificate Pinning:
In order to demonstrate how to use certificate pinning for protecting the https traffic between your mobile app and your API server, we will use the same Currency Converter Demo mobile app that I used in the previous article.
In this article we will learn what certificate pinning is, when to use it, how to implement it in an Android app, and how it can prevent a MitM attack.
What to pin?
From the same article I will quote:
The easiest way to pin is to use the server’s public key or the hash of that public key, The hashed public key is the most flexible and maintainable approach since it allows certificates to be rotated in the server, by signing the new one with the same public key. Thus the mobile app does not have to be updated with a new pin because the hash for the public key of the new certificate will continue to match the pin provided in the network security config file. We will see an example of this later when we talk about how to setup certificate pinning.
Implementing Static Certificate Pinning
The easiest and quick way you can go about implementing static certificate pinning in a mobile app is by using the Mobile Certificate Pinning Generator that accepts a list of domains you want to pin against and generates for you the correct certificate pinning configurations to use on Android and iOS.
Give it a list of domains to pin:
And the tool generates for you the Android configuration:
And the iOS configuration too:
The tool even as instructions how to go about adding the configurations to your mobile app, that you can find below the certificate pinning configuration box. They also provide an hands on example Pin Test App for Android and for iOS that are a step by step tutorial.
Bypass Certificate Pinning
It's important that any developer that decides to implement certificate pinning in their mobile apps also understands how it can be bypassed in order to learn the threat model and evaluate if further protections are needed to prevent certificate pinning bypass.
I wrote two articles on how to bypass certificate pinning on Android where you can learn in one of them how to do it by extracting, modifying and repackaging the APK, while in the other article you learn how to use the Frida instrumentation framework to hook at runtime into the mobile app in order to bypass certificate pinning:
Bypassing Certificate Pinning on Android via APK
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.
How to Bypass Certificate Pinning with Frida on an Android App:
Today I will show how to use the Frida instrumentation framework to hook into the mobile app at runtime and instrument the code in order to perform a successful MitM attack even when the mobile app has implemented certificate pinning.
Bypassing certificate pinning is not too hard, just a little laborious, and allows an attacker to understand in detail how a mobile app communicates with its API, and then use that same knowledge to automate attacks or build other services around it.
Summary
Despite being possible to bypass certificate pinning I still strongly recommend you to implement it in your mobile app, because it reduces a lot the attack surface of your mobile app.
Being aware of how certificate pinning can be bypassed gives you the insights to decide if further protections are needed to be in place. Dynamic certificate pinning and Runtime Application Self-Protection(RASP) may be the next steps to take in your security ladder.

Will HTTPS API for a mobile app protect against Wireshark and similar?

Suppose I have a mobile app which makes API calls to a server using HTTPS.
Would a malicious user be able to install Wireshark + Android emulator to inspect the API calls and by doing so get access to sensitive data like an API key?
I guess my question is whether Wireshark (or some other tool) can inspect the request before it gets encrypted.
If you control the client, then of course yes. Anything the client knows, its user may also know.
Without controlling the client, no, an external attacker cannot inspect or change https traffic unless they know the session keys. For that, they would typically use a fake certificate and make the client accept it (it won't do it by itself, and we are back at controlling the client).
Would a malicious user be able to install Wireshark + Android emulator to inspect the API calls and by doing so get access to sensitive data like an API key?
I guess my question is whether Wireshark (or some other tool) can inspect the request before it gets encrypted.
Yes this possible if the user controls the device he wants to intercept the API calls.
In the blog post Steal that API Key with a Man in the Middle Attack I show how a proxy tool(MitmProxy) can be used to intercept and introspect the https calls:
While we can use advanced techniques, like JNI/NDK, to hide the API key in the mobile app code, it will not impede someone from performing a MitM attack in order to steal the API key. In fact a MitM attack is easy to the point that it can even be achieved by non developers.
In order to protect https calls from being intercepted, introspected and modified the solution is to use certificate pinning:
Pinning is the process of associating a host with their expected X509 certificate or public key. Once a certificate or public key is known or seen for a host, the certificate or public key is associated or 'pinned' to the host. If more than one certificate or public key is acceptable, then the program holds a pinset (taking from Jon Larimer and Kenny Root Google I/O talk). In this case, the advertised identity must match one of the elements in the pinset.
and you can learn how to implement it in the article 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.
You also learned that certificate pinning should be used anytime you deal with Personal Identifiable Information or any other sensitive data, otherwise the communication channel between the mobile app and the API server can be inspected, modified or redirected by an attacker.
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.
While certificate pinning raises the bar, its still possible to intercept, introspect and modify https traffic, because it can be bypassed, as I demonstrate in the article Bypassing 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.
Conclusion
While certificate pinning can be bypassed I still strongly recommend its use, because it will protect the https communication channel betwwen your mobile app and API server in all other scenarios where is not the user trying to perform the Man in the Middle attack:
In cryptography and computer security, a man-in-the-middle attack (MITM) is an attack where the attacker secretly relays and possibly alters the communications between two parties who believe they are directly communicating with each other. One example of a MITM attack is active eavesdropping, in which the attacker makes independent connections with the victims and relays messages between them to make them believe they are talking directly to each other over a private connection, when in fact the entire conversation is controlled by the attacker. The attacker must be able to intercept all relevant messages passing between the two victims and inject new ones. This is straightforward in many circumstances; for example, an attacker within reception range of an unencrypted wireless access point (Wi-Fi[1][2]) could insert themselves as a man-in-the-middle.[3]
Going 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.
HTTPS request is encrypted on your host (client) before sending over the network, so it is not available for Wireshark. Wireshark can get hostname of the HTTPS web serserver you connect but not the URL.

WCF with HTTPS and Windows Phone 8

I am working on a small service accessed from a client on Windows Phone 8 and/or WinRT device that requires a moderate amount of security. My goal is to create a service that runs in Windows Azure.
My application requires authentication that verifies two things:
1) Authenticity of the client
2) User credentials of the client
Step 1) I need be certain to a fair degree that the application calling the service is, in fact, my client application.
Step 2) The user needs to have an account in the system that can be authenticated. I can implement the authentication by simply making a Login() method in the interface (unless there is a better way). However, for this, the communication between the client and the server needs to be secure as I do not want my username+password combo unencrypted.
My current view is that implementing it as a WCF service would probably be the way to go as I might have further interest into porting to other platforms on the client-side and a quick look showed me that this is somewhat supported.
However, as I am new to all these certificate shenanigans, my question is whether I can use self-signed certificates for securing my connection? Only my server and my client need to be able to verify the authenticity. Furthermore, any pointers to exactly how this is done in the WP8 + Windows Azure case?
Another deal is that assuming that a nifty hacker breaks open my program from the client hardware, can he take the certificate and use it to create his own client to login with (his) username/password and performing actions performed by my original client? Or is there a way to prevent this on the client side? In other words, can my server be sure of the authenticity of the client software based on having a valid certificate signed by me?
Step 1 is pretty much impossible. No matter what attestation method you use in code it can be duplicated in code by another programme.
Step 2 doesn't require WCF, although you can use it with basic auth. It's just as easy to expose a RESTful service with WebAPI which supports basic auth as well. Securing the communication is the same for either WCF or WebAPI - use SSL.
WCF does not like self signed certificates, and configuring it to use them does away with some of the security, depending on how you do it. Given that SSL certs from trusted CAs start at around $10 it would be a false economy not to get one. Azure webworkers support SSL certs, and support for Azure Web Sites is coming, although with no firm date.
Finally a client certificate in managed code can be reasonably easily extracted, so you cannot rely on it to identify client code.

mobile application: how do I provide client authentication

I had an idea for a fitness mobile app and I have been developing applications based on this idea for iPhone (Obj-C based), Android (java based), WebOS (html5 based) and Nokia Qt.
I now need to provide authentication to the users of my application. The server is a typical LAMP system. I would like the users of my mobile application to log in to the server seamlessly and securely.
I am not really a web programmer and hence would appreciate ideas on how I can go about providing authentication. I've heard about OpenID...but I am not sure if it can be used for authenticating mobile clients. Some one mentioned OAuth but I am not sure if a) it would work in this use case and b) What if my client does not have a Facebook/Twitter account?
Any ideas will be appreciated!
I have done something similar and used gnuTLS and a x.509 certificate to authenticate from the client side. Its seamless and easy to integrate.
https://idlebox.net/2009/apidocs/gnutls-2.6.6.zip/gnutls_7.html#SEC65
The important thing about using this method for me was that the https connection was just simple method calls and the handshaking process itself would be handled by the gnuTLS library.
My app was an iOS app and i used xcode to do it which was easy. I think it will be easier on the Java side but I am not sure about the Nokia part. The coding is in C and is thus cross platform.
However if you are looking for a iOS based solution i recommend http://developer.apple.com/library/ios/#samplecode/AdvancedURLConnections/Introduction/Intro.html
But for a cross platform solution that would require the same certificate across all applications and no input or work fro the user, I still suggest gnuTLS and using the x509 certificate.
If you already have a LAMP server somewhere, it should be fairly easy to set implement your own API for password authentication -- the important thing is that you do it via HTTPS! (so the user-ids / passwords can not be sniffed). You will need a digital certificate (CERT) for your web-server.
On your LAMP system you can keep the user data in it's database. Your LAMP server should also allow to create a local user account (of course).
You can use this solution either separate or together with OpenID or OAuth!
That means, if your client doesn't have Facebook or Twitter, they can still create an account on your LAMP server.
http://en.wikipedia.org/wiki/OAuth