I'm fairly new to SSL and secure connections in general. What are the major steps required for an iOS app to talk to a server over a secure communications channel?
I'm aware that an SSL certificate will probably be necessary. I'm planning to purchase one from a trusted certificate authority. However I'm not sure if both the app and the server need certificates or if it's just the server. Also I'm not sure how to handle SSL errors. Perhaps there's a library that can help with this like ASIHTTPRequest or similar.
If you are using HTTPS as your protocol for communication and have valid certificates on your server all that should be required is changing your http:// to https:// on your client. For HTTP libraries a very popular option now is AFNetworking. It is a bit better maintained than ASI and has some nice block features not supported by ASI.
As far as SSL errors, it is usually a good idea to present the warnings to end users (through alert views or some other means). They could point to real security attacks (but more likely will point to miss configured or expired certificates).
Related
I'm an iOS Developer and I have one question about security that I can't answer.
Security experts say that using the "certificate pinning" will make your app more secure (for example against man in the middle attacks).
I agree that with this technique you can guarantee that your app is communicating with your backend (and that no-one "in the middle" can sniff the traffic), but as we are using HTTPS, the traffic is already encrypted, so how could someone see the traffic?
There is one possible way, that you get the certificate of the attacker and you install it on your iPhone, but is this really something that can happen ? Or are other ways to make this kind of attack?
HTTPS and Ceritificate Pinning
Security experts say that using the "certificate pinning" will make your app more secure (for example against man in the middle attacks).
That a best practice in terms of security in order to avoid the MitM attacks that you already know, but do you know what certificate pinning works?
I know that your question is about iOS but in my article Securing HTTPS with Certificate Pinning on Android you can learn for what certificate pinning is for and why is needed, because this is agnostic of the mobile platform being used. Please read the article and feel free to ignore the part about implementing pinning in Android.
To give you some context I will quote some of the more relevant parts of my article, that will help clarifying your doubts.
Lets' start with the part about why we need Certificate Pinning:
While HTTPS gives you confidentiality, integrity and authenticity in the communication channel between the mobile app and the API server, certificate pinning will protect these same guarantees from being broken.
Let's see two examples from the article on how the HTTPS guarantees can be broken.
First Example:
To prevent trust based assumptions
Incorrectly issuing leaf certificates to the wrong domain names by Root and Intermediate Certificate Authorities (CAs) would allow an attacker to intercept any HTTPS traffic using them, without the end user noticing anything.
Do you think that is very unlike for this to happen? Just take a look to the famous cases of DigiNotar, GlobalSign and Comodo.
Second Example
Another scenario where the HTTPS guarantees are usually broken is when the device is running in hostile environments:
A good example of a hostile environment is public WiFi, where users can be tricked by an attacker into installing a self signed root certificate authority into the trusted store of the device as a requirement for them to have internet for free. This will allow the attacker to perform a MitM attack and intercept, modify or redirect all HTTPS traffic, because the device will now accept all intercept traffic which is now signed by the root CA of the attacker - now trusted by the device.
Both examples will allow for attackers to see the HTTPS encrypted, thus I hope it answers your question:
I agree that with this technique you can guarantee that your app is communicating with your backend (and that no-one "in the middle" can sniff the traffic), but as we are using HTTPS, the traffic is already encrypted, so how could someone see the traffic?
So, HTTPS will encrypted your traffic in transit and certificate pinning will try to prevent it from being decrypted. Wait, did you said try? Yes, because pinning can also be bypassed in a device the attacker controls. I have several articles (1, 2) on it, but on Android, and for iOS it can also be done, and its on my backlog, thus I will update this answer when done.
Possible Attacks to your Mobile App
There is one possible way, that you get the certificate of the attacker and you install it on your iPhone, but is this really something that can happen ? Or are other ways to make this kind of attack?
An attacker will reverse engineer your mobile app in order to understand how everything fits together and will try then to exploit flaws in your logic and security. For example, the attacker can use the MobSF - Mobile Security Framework to statically reverse engineer your mobile app binary:
Mobile Security Framework is an automated, all-in-one mobile application (Android/iOS/Windows) pen-testing framework capable of performing static analysis, dynamic analysis, malware analysis and web API testing.
Attackers will often perform attacks to your code at runtime to modify its behaviour or bypass certificate pinning and a popular tool used for this propose is 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.
Bear in mind that the attacker can be a legit user of your mobile app trying to bypass some of the limitations of the plan is on in order to get more then what he is entitled to.
Want to Implement Certificate Pinning on iOS?
If you want to go ahead and implement certificate pinning in your iOS mobile app then you can use the Mobile Certificate Pinning Generator free tool to get the iOS configuration generated for you.
First you need to provide the API domains you want to pin:
After you submit the form you need to go to the iOS tab to see your iOS configuration and copy/paste it into your mobile app code:
Do You Want To Go The Extra Mile?
In any response to a security question I always like to reference the excellent work from the OWASP foundation.
For APIS
OWASP API Security Top 10
The OWASP API Security Project seeks to provide value to software developers and security assessors by underscoring the potential risks in insecure APIs, and illustrating how these risks may be mitigated. In order to facilitate this goal, the OWASP API Security Project will create and maintain a Top 10 API Security Risks document, as well as a documentation portal for best practices when creating or assessing APIs.
For Mobile Apps
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.
OWASP - Mobile Security Testing Guide:
The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.
Yes, you need to install a root CA certificate on the iOS device and trust it for making an man-in-the-middle attack on an HTTPS connection used by an iOS app.
But you forget one major case: What happens if the attacker and the iPhone user are the same person? Having access to the transmitted data makes it easier to analyze you app and find potential flaws. So an attacker can install your app on a prepared device, analyze it, find all the mistakes you made and afterwards attack use this knowledge to attack your server(s) and/or your app users.
Another scenario is that people are forced to install root CA certificates may be because the phone is used in a company with own network inspection or at a border control.
Last but not least the recent attack on KlaySwap crypto shows you why certificate pinning is so important: in that attack the BGP was attacked to redirect traffic to a specific web server hosting a JavaScript file to a malicious server. After redirecting the traffic the attackers just used ZeroSSL to create a new 100% valid SSL/TLS certificate which they installed on their malicious redirected web server.
There are two prior questions leading to this question (if you're interested):
ssl-for-intranet-applications-deployed-at-multiple-companies
distributing-ssl-certificates-to-all-browsers-in-an-active-directory-environment
In Electron, do you have the ability to override SSL certificate warnings that you'd typically get when using self-signed certificates via a modern web browser?
Typically, in desktop applications, you do not have to adhere to the strict online-banking-level certificate standards that web browsers warn about. The data I'm transferring isn't that sensitive.
As a matter of fact, one of the only reasons I'm moved my app from http to https, is because certain web standard APIs won't function unless the protocol is https. The Notification API is one example.
Otherwise, the data I'm transferring over intranet just isn't that sensitive. Yet, the browsers attempts to burden me (and my users) with Online-Banking-Level certificate authentication.
I'm trying to avoid this somehow and thought that maybe Electron could give me more client-side control for pre-approving my self-signed certificate. Is this doable in Electron?
I have some trouble with https and untrusted proxy certificates and this in my index.js
// We have to deal with self-signed and therefore untrusted root certificates.
global.process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
It's an intranet application that never reaches out to the internet, so it's ok for me here.
We are building an end to end solution that will allow our customers to access their ERP data hosted in their own servers through mobile applications. Version 1 will be an iOS app.
We need to make sure the traffic between the client and the server is encrypted with SSL. The problem lies in that we want the installation of the server to be as seamless as possible, hence we don't want the customer to go through the process of buying and installing SSL Certificates. Not even mentioning having to renew that certificate every year.
We were thinking of creating a self signed CA certificate and use it to create child certificates for each client to install on their servers (along with the public CA certificate). We would automate the process of creating the child certificate and include it as part of the setup process. The certificate will also have a very long expiration date as to not dealing with expirations. But if we use this certificate the requests from the client won't be trusted as the CA won't be trusted.
Can the CA be added to the iOS app or device?
Is there a security concern with this implementation?
I have a very similar situation. So far I have just created self signed certificates and just programmed the clients to ignore allow untrusted SSL certificates. If there is a better answer I'd love to hear it.
It is 2017 and letsencrypt now exists, which provides free domain validation and signing of TLS certificates such that browsers / OS HTTPS or TLS libraries and frameworks will accept them, and through certbot it is relatively easy to set up auto-renewal. I won't describe it here because it's deployment specific, but they have good docs. Combined they're probably the best solution out there.
Bundling and using self-signed certificates is seriously sub-optimal for various reasons, and there's no reason to do it anymore (except perhaps gross laziness), so don't.
Free is only for basic domain-validated certificates, i.e. where letsencrypt.org validates that you own the domain that you say you do (and certbot is used to automate that process). You still need to pay for extra verification steps if you want them. However, for internal TLS connections between your app and your server, you only really need domain validated, because you only have to be sure you are talking to your server. The extra steps are more focussed on giving a customer confidence in a company, so they can give over sensitive data with greater peace of mind. Generally speaking if they are using you app, that suggests they trust your company already, so the extra validation is not important (and probably invisible to the customer anyway).
In development if you want to use self-signed certificates this may still make sense. Check out my answer to this question on how to install self-signed certificates for all apps on your iOS device.
I'm setting up a server to do receipt verification for IAP on the App Store.
My question is: Should I make the connection between the iOS device and my server as a https connection, or does http suffice? All the examples I seen people are just using http.
It seems that if I use http, then it's venerable to a someone redirecting the DNS. Or does that not matter? Seems like it would.
Of course, I'm such small potatoes that it's probably not worth the hassle.
It is always desirable to use https (encrypted) connection when you are passing some credentials or sensitive information such as financial transactions. May be it is not possible for anyone to mangle the transaction itself but still, you are breaching the confidentiality aspect of financial transactions which your client might not like.
However, it is not just https which can help, you can also implement your custom encryption in the application to make the communication secure (may be the security is not strong but does work in cases where you really do not need an overkill). Try to encrypt the data with a pre-shared key and decrypt it on the server (which I do myself many times).
I'm working on an ios application without authentication. Now I would like to protect my server API from calls other then my ios application. A possible solution would be to have the application generate a unique key (based on the appname and the signing), which is not stored on the device since this is the main problem. I could think off an application logic that does some protection combined with some file encryption but the problem is that somewhere something is stored (ex public key can be stored in keychain but still not safe for my API-hackers).
Anyone any tips/advice on how I can handle this ?
thanks in advance
In short, there is no 100% secure way to make sure that the request comes from your application, if the key is available to the iPhone, it's available to extract from the iPhone.
You can make it reasonably safe by calculating a key runtime from info in the application as you say and communicate it over SSL, but a determined attacker can always reverse engineer the key generation too.
What you want to do is employ mutually-authenticated SSL, so that your server will only accept incoming connections from your app and your app will only communicate with your server.
Here's the high-level approach. Create a self-signed server SSL certificate and deploy on your web server. You can use freely available tools for this, like keytool, and I think (but don't know for sure) that Apple includes a tool for this with the iOS SDK. Then create a self-signed client and deploy that within your application in a custom keystore included in your application as a resource. Configure the server to require client-side SSL authentication and to only accept the client certificate you generated. Configure the client to use that client-side certificate to identify itself and only accept the one server-side certificate you installed on your server for that part of it.
If someone/something other than your app attempts to connect to your server, the SSL connection will not be created, as the server will reject incoming SSL connections that do not present the client certificate that you have included in your app.