What is the best way of implementing App Transport Security? - ios

I'm making a web browser and I'm in the process of finalizing the application and submitting it to the app store.
One of the things I left for last is App Transport Security.
I know it's forced so Developers use https:// instead of http:// but a web browser can't be limited like this.
Is there anything else I can do besides adding "NSAllowsArbitraryLoads: YES" to the info.plist file?

For iOS 10+, you can evaluate using NSAllowsArbitraryLoadsForMedia,
NSAllowsArbitraryLoadsInWebContent,
NSRequiresCertificateTransparency or
NSAllowsLocalNetworking instead of the highly insecure ArbitraryLoads: YES.
However, for a web browser application, I don't see much of an alternative besides ArbitraryLoads: YES. You can consider implementing alerting the user when loading such sites.
This is the complete guide to ATS

Related

Displaying web images valid excuse for using NSAllowsArbitraryLoads?

Until now, we have only been setting NSAllowsLocalNetworking in our app's ATS settings.
However, are now introducing link previews in our chat functionality. Links posted by a user are used to create a preview containing both the linked webpage's image and favicon.
The problem is that some links posted by users have favicons/images in clear-text (HTTP) format.
Is this a valid reason for using NSAllowsArbitraryLoads?
I am not 100% sure on the current status of ATS enforcement and whether user-generated links would be an acceptable exception.
(We are using the Kingfisher library to display these images in a UIImageView so NSAllowsArbitraryLoadsForMedia with AVFoundation is not possible.)
Although I cannot be certain what Apple will consider a valid reason (since they haven't started enforcing, so we have no information to go off of), having user driven content in the app seems like it would be one of those scenarios that would require the broader NSAllowsArbitraryLoads exception.
What I would recommend, in order to show Apple that you've done all that you can to secure any communication you can, would be to do the opposite of the most common technique. Normally, apps will leave ATS enabled (by leaving the default of NSAllowsArbitraryLoads as NO) while adding exception domains that disable ATS for certain domains. If I were you, I would do the opposite - set NSAllowsArbitraryLoads to YES, since you can't know what URLS might need ATS exceptions, then add exception domains for the domains that you control in the app (assuming there is some main server you get most of the app content from). This ensures communications with your server are secured using ATS standards, while all outside of the known servers will be exempt from ATS requirements.So turn ATS off, but turn it back on for domains in your control.
From this great article on some common ATS configurations, you can see how you would set things up this way ("Example C: ATS disabled, with some exceptions"):
To me, this would be a good sign to Apple that you are trying as much as possible to comply with the spirit of ATS.
You won't be rejected. The last update from Apple on this deadline was this:
At WWDC 2016 we announced that apps submitted to the App Store will be
required to support ATS at the end of the year. To give you additional
time to prepare, this deadline has been extended and we will provide
another update when a new deadline is confirmed.
https://developer.apple.com/news/?id=12212016b

iOS9 : App Transport Security inside .plist Framework

I had create a Framework that using NSURLSessionDataTask (HTTP) to send request to server, but whenever I use the Framework in Example app, it show warning like this :
App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.
I tried to add App Transport Security inside Framework .plist but still not working. But, It work when I add App Transport Security in .plist outside Framework.
Is there any solution for this problem ?, Thanks
As #EmilioPelaez stated, the application controls whether ATS is active or not. If your framework does something that violates the ATS rules, each app that uses the framework will need to add the appropriate exceptions.
There is good reason for this behavior. Take, for example, a generic network helper framework, where the URLs are provided to the framework calls by the calling application. The framework would have no way of knowing whether it will need ATS. Conversely, if the framework has hard-coded URLs in it that require ATS exceptions, the calling app developer should be aware of that and it shouldn't be obscured by the face that the framework developer added exceptions. I, as a developer, would want to know I was using a framework that was inherently insecure. If you are dealing with the latter scenario, simply put in your framework documentation the exceptions that are needed for the framework to function properly.
Also, as a best practice with ATS, don't just disable it altogether, there are specific exceptions that can be used to minimize your security risk exposure by only disabling certain parts of the ATS requirements for specific domains. Be sure you do that. Also, understand that Apple planned to require justification for many ATS exceptions at the end of 2016, but it has been postponed at the moment. If you add exceptions, you should be prepared that at some point, when you submit the app to the App Store, you will be asked by Apple for a reason. It probably shouldn't be "because stack overflow told me to disable all ATS".
The framework doesn't have control over ATS, the app does. So you have to write it down in your documentation, that the app developer needs to add ATS exceptions to his app.
That said, don't do that. Especially if you're making a framework. Take time and add HTTPS support to the server / contact the server developer to add it. Because Apple will stop supporting AllowArbitraryLoads / exceptions soon. So, apps that include your framework won't be able to get through a review process without providing a valid reason for why they need those exceptions. Apple originally planned to drop the support starting Jan 1st 2017, but they postponed it for an unknown period of time. Still, they'll do it some day. It's better to plan for the future.
P.S. If you have absolutely no control over the server, and the server developer is on Mars, and your framework really needs to communicate to that server, the app developers will probably be able to pass the review by explaining the situation ("no control over the server" is a valid reason for the Apple Review team), but each and every one of them will have to do it over and over again, and you'll have to explain in your documentation how to do it and what to say. So switching to HTTPS is easier.
Add NSAllowsArbitraryLoads as true key in your info.plist to avoid this issue.

Are Universal Links cached in iOS? Do they work offline?

I tested Universal Links in iOS by turning on Airplane mode and saw that the correct application was opened (instead of a website)
This indicates some level of "caching" the apple-app-site-association.
I want to determine the extent to which this is cached, so I can determine
What UX edge cases are there (e.g. Offline for x days)
What security considerations are there (e.g. MITM / SSLStrip + .well-known/URL)
etc.
Ideally I would like to have details if additional logic is employed (conditional caching if HTTPS employed, DNSSec, etc)
The exact behavior here is (intentionally?) unclear from Apple. Here is my personal experience, gleaned partly from official documentation and partly from helping thousands of apps implement Universal Links at Branch.io.
The apple-app-site-association file is cached once when the app is first installed.
If this initial scrape fails, in almost all situations it will not be reattempted. The only exception to this is if the initial return is a 5xx error, in which case a limited number of retries may occur. This is not well-documented, and is not covered in Universal Links documentation at all. You can find a mention in the Shared Web Credentials docs.
The file is not checked at all when a Universal Link is opened. This is why you are able to get Universal Links behavior in airplane mode.
The file does not expire. Once it is cached, it sticks permanently for as long as the app is installed.
The file will be re-checked when installing an app update.
The file must be accessible via a valid SSL connection at either https://example.com/apple-app-site-association or https://example.com/.well-known/apple-app-site-association. If there are redirects of any kind, this will fail.
It is theoretically possible to MITM the request if you are able to install a new SSL certificate directly on the device in question. Charles Proxy for example uses this approach for debugging. I have never seen or heard of this being exploited, and the damage would be quite limited because the domain still has to be specified inside the app itself.
I found a way to get around the caching issue. The cache is bound to the domain name, so for every time you want iOS to request apple-app-site-association you can create a new subdomain, and configure iOS to use that subdomain as the universal link for your app.
Extremely hacky, but it is the only workaround that worked for me.

iOS 9 Transport Security Policy not blocking all http connections (only https was supposed to be allowed)

I have already researched and tested a lot this new feature of iOS 9, where the "Transport Security Policy" states that all HTTP requests would be blocked and only HTTPS would be allowed.
During my tests, I could download and render an image from an http ONLY link. After that, I put a http link to redirect the image's click and the TSP blocked my request.
Anyone has had this issue before?? What does the TSP actually block??
OBS.: I was NOT using a webview of any kind, before anyone asks...
Thanks!
In your Info.plist you can add a section that lists exceptions for the TSP. You can put http domains in that section. Hopefully that helps.
I haven't run into the exact issue you're describing.
TSP, officially referred to as App Transport Security (ATS), when enabled, forces you to use HTTPS.
Apple has a great documentation page, which gets into a lot of details about what would and wouldn't get blocked.
If you're asking in order to get around it, you can include an NSAppTransportSecurity dictionary in your Info.plist. In it you can have specific domains for which you'd like an exception (NSExceptionDomains) or turn the whole thing off (NSAllowsArbitraryLoads : YES). Note that the spirit of the latter is for an app that allows the user to specify the connection info, not exactly to work around security best practices.

Can I set a device level proxy within an iOS app? How?

Can I develop an app that uses a specified HTTP proxy for all web requests? If yes, how can I implement such feature in the app? (any similar links are also useful)
And, can I set this proxy configuration to device level from within the app?
Please direct to any related information or reading. Thanks :)
You can't change the device configuration from within the app, imagine how insecure would be if apps could do it, they could redirect all the phone traffic to their proxies.
And for doing it on your own app, you'll have to do it yourself too, try creating your own url request subclassing NSURLRequest
A standard app store app cannot do it, but apparently a select few apps have been blessed with additional non-standard, undocumented entitlements by Apple to enable the setup of a device-wide VPN configuration. See http://blog.michael.kuron-germany.de/2010/09/ios-4-1-undocumented-vpn-api-used-by-cisco-anyconnect/ for some hints on how that works.

Resources