In my app, APIs provide the domains for images and videos during runtime and I need to allow these connections to be made. Using NSAllowsArbitraryLoads seems to be the only satisfactory thing I can do right now, but I would like to take advantage of ATS and only whitelist this short list of domains provided at runtime.
According to the App Transport Security Technote, all of these domains are set in the Info.plist, which is copied at compile time. Is it possible to allow HTTP or loosen TLS requirements during runtime for requests to these specific domains?
No, the ATS policy is defined at compile time. My guess is that it may be so that it becomes part of the signed application package and can't be tampered with.
In your case allowing insecure transfers generally wil be required. If the API endpoints you use support TLS then you can specific those domains as exceptions that require security in the policy file.
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.
I was integrating Sign in with Apple in my mobile app. I followed the configuration steps provided in the developer portal and downloaded the apple-developer-domain-association.txt file and placed it on my server at the given path. Now the file is loading from web browser but I'm not able to verify my domain on Apple developer account. Its giving me an error message "Verification failed for domain".
Anyone got same issue? how to get verified sucessfully
To verify domain to configure Sign in With Apple apple-developer-domain-association.txt file must be accessible publicly.
https://{YOUR_DOMAIN}/.well-known/apple-developer-domain-association.txt
Make sure
Domains and domains associated with email addresses must comply with Sender Policy Framework (SPF) standards.
Must be accessible via https. http doesn't work.
No redirect not even to wwww. Example url mentioned above must serve the apple-developer-domain-association.txt file without any redirects.
Hint: if you are serving apple-developer-domain-association.txt with www than you must register domain www.{YOUR_DOMAIN} white configuring sign in with apple configuration on developer.apple.com. To do that you have to make sure www.{YOUR_DOMAIN} is SPF compliance.
In continues and addition to #Bilal
A. If the domain is not SPF compliant you will be noted immediately when trying to add it in the developer portal
B. If you not sure whether your site is redirected yo can check it in http://www.redirect-checker.org/ or just use postman and disable 'Automatically follow redirects' option in the request settings
C. Apple require that your server must support the Transport Layer Security (TLS) 1.2 protocol and one of the cipher suites listed below:
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
TLS_RSA_WITH_AES_128_GCM_SHA256
TLS_RSA_WITH_AES_128_CBC_SHA256
For me the problem was the www redirect I had no clue our servers do that, my devops helped me solve this just for the verification.
Best solution IMO is just use your own relay microservice with a unique dedicated domain...
To expand on #MTZ4's response (upvoted BTW because you nailed it), here is the process that I needed to work through, with some pointers to anyone else not quite as familiar with working through these types of problems.
In my case, I had CloudFlare dealing with both the DNS and TLS cipher certificates and Heroku serving the site.
The first step is determining whether your TLS provider serves the appropriate TLS ciphers required by Apple.
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
TLS_RSA_WITH_AES_128_GCM_SHA256
TLS_RSA_WITH_AES_128_CBC_SHA256
One of the easiest way's to do this is by using SSL labs certificate checker. Simply enter your root domain and let the report run (takes a few minutes). In the report response, look for the section Cipher Suites and verify the TLS ciphers Apple wants are available. In the image below you can see them in orange and marked as weak.
You can ignore the weak status, this is because these ciphers do not use ephemeral keys and will not be used in TLS 1.3.
If you want a more comprehensive test, install NMAP and then download the ssl-enum-ciphers script. After installing NMAP and downloading the script, execute the script against your domain:
nmap --script ssl-enum-ciphers -p 443 my-root-domain.com
This produces a result set that looks like this:
Once again look for the TLSv1.2 section and check your list of ciphers against Apple's list. If they are not present (they are missing in the image above), then that is where your problem lies.
So how to fix? Well there are a few options and it all depends upon your TLS provider, which may be your web host or may be your DNS host depending upon your configuration.
For us, we are using CloudFlare as our DNS provider. CloudFlare also provides the TLS ciphers. Because CloudFlare does not support the ciphers Apple requires (the NMAP image above) and they won't add them due to their security concerns about TLS 1.2 and moving to TLS 1.3, we had to disable CloudFlare's proxy service to allow the TLS certificates that were being provided by our hosting service (Heroku).
This turned out to be easy. Just logging into CloudFlare, going to the DNS entries and changing the traffic routing behavior (click the orange cloud to make it grey for verification, then click it again once verification is done). For more information see CloudFlare's support page.
After doing this, Heroku was serving the TLS ciphers, which include the Apple required ones (as shown in the SSL Labs image above).
Ultimately whoever is serving your TLS ciphers must include the ones Apple needs. If your tests above don't show the correct ciphers, check your DNS/TLS service and your hosting provider to see if they support them. If they don't, then you may need to switch.
Finally, it is also worth noting that in Apple's developer portal, when you click the download button for the verification file, do not click it again! Each time you click the button, the verification file changes as it seems to be dynamically generated.
Just fix all the TLS issues, then log into the Apple developer portal, download the file, upload to your server and then verify.
I did end up working with Apple support on some of this and they are looking at adding some documentation to the verification page that states what ciphers are needed so others don't hit the same problems.
I'm running node js and express and had the issue because I bought a cheap SSL cert from Sectigo.
Here's what I did to fix it.
Check your SSL certificate for errors https://www.digicert.com/help/
I had to install an intermediate certificate. That solved the issue.
If you perform the check in Safari, it won't give you a confirmation that the domain is verified.
Instead, perform the check in Chrome and it will give you a confirmation.
Inspect the HTTP header coming back from your server. If it's a 301 Apple won't follow it. Instead, the verification file must be returned via 200 HTTP status code. The verification file I'm referring to is https://example.com/.well-known/apple-developer-domain-association.txt where example.com is your domain.
If you are using Cloudflare free tier, upgrading to the PRO plan (currently $20/month) does the trick. All their paid plans include the required ciphers.
And of course, you can always cancel the plan after verifying and go back to free.
As announced in WWDC 2016, Apple will enforce HTTPS connection for all apps from December end 2016.
Although I have added all the HTTP domains to which my app communicates as exceptions in the ATS settings but not sure how to handle one particular case where in if I refer to a HTTP connection added as ATS exception in info.plist which internally redirects to another HTTP connection which is not part of the ATS exceptions added in info.plist.
Please suggest.
Unfortunately, if you don't know the domains for the destination of the redirects, you will have to disable ATS using the NSAllowsArbitraryLoads key in your info.plist.
Apple will allow you to do this, as long as you have a valid justification. If you are accessing third-party sites that do the redirection, and you do not have control over those sites, that may be a valid justification when you submit the app. What you could do to increase your chances that Apple accepts your justification, is to include exception domains in your info.plist for all the domains that you do know are secure. A combination of NSAllowsArbitraryLoads and exception domains with ATS turned on will at least show Apple that you are trying to be as secure as possible within your app.
I am using a single https static URL in my iOS application. I want to secure that using ATS. I am confused which exception should be used in .plist file.
1-NSIncludesSubdomains
2-NSExceptionAllowsInsecureHTTPLoads
3-NSExceptionRequiresForwardSecrecy
4-NSExceptionMinimumTLSVersion
5-NSThirdPartyExceptionAllowsInsecureHTTPLoads
6-NSThirdPartyExceptionRequiresForwardSecrecy
7-NSThirdPartyExceptionMinimumTLSVersion
Thanks in advance
You don't need to add any flags in ATS to enable secure communication. ATS flags are used to exclude domains from requiring https communication.
Make sure your url you use starts with https and it will connect securely.
Now, there are more advanced things you can do, such as certificate pinning, but that doesn't involve ATS, and I'd recommend using something like Alamofire to help do all that configuration properly.
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).