iOS9 : App Transport Security inside .plist Framework - ios

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.

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

Your app, extension, and/or linked framework appears to contain code designed explicitly with the capability to change your app’s behavior [duplicate]

My latest build was accepted into the Apple app store, but I got the notice quoted below a couple of days later.
My app also uses Rollout.io, and I asked explicitly if this was the problem. No response yet.
If respondsToSelector or performSelector are banned, are there any replacements?
Dear Developer,
Your app, extension, and/or linked framework appears to contain code designed explicitly with the capability to change your app’s behavior or functionality after App Review approval, which is not in compliance with section 3.3.2 of the Apple Developer Program License Agreement and App Store Review Guideline 2.5.2. This code, combined with a remote resource, can facilitate significant changes to your app’s behavior compared to when it was initially reviewed for the App Store. While you may not be using this functionality currently, it has the potential to load private frameworks, private methods, and enable future feature changes.
This includes any code which passes arbitrary parameters to dynamic methods such as dlopen(), dlsym(), respondsToSelector:, performSelector:, method_exchangeImplementations(), and running remote scripts in order to change app behavior or call SPI, based on the contents of the downloaded script. Even if the remote resource is not intentionally malicious, it could easily be hijacked via a Man In The Middle (MiTM) attack, which can pose a serious security vulnerability to users of your app.
Please perform an in-depth review of your app and remove any code, frameworks, or SDKs that fall in line with the functionality described above before submitting the next update for your app for review.
EDIT:
Apple forum mentions this: https://forums.developer.apple.com/thread/73640
It is not respondsToSelector:, performSelector: that are banned. The ban is on putting dynamic content as a parameter to this method. For example, this is not banned:
if([self.delegate respondsToSelector: #selector(myDelegateMethod)]) {
[self.delegate performSelector: #selector(myDelegateMethod)];
}
However, this code might be banned:
NSString *remotelyLoadedString = .... (download from your backend)
[self performSelector: NSSelectorFromString(remotelyLoadedString)];
On March 8th 2017, Apple warned all the developers of JS injection. This includes libraries like:
JSPatch
Rollout.io
AMapFoundation as it includes JSPatch [edit: they now provide a new version without it]
Bugly as it includes JSPatch [edit: they now provide a new version without it]
GTSDK as it includes JSPatch [edit: they now provide a new version without it]
...
If you are directly using a service like JSPatch or Rollout.io, you should stop using it.
If you are using a third-party that was depending on JSPatch indirectly, you should request an updated version of your third-party that does not include JSPatch anymore.
dlopen
dlsym
respondsToSelector
performSelector
method_exchangeImplementations
Sometimes some people used to think all above methods are banned but the exact issue is, those methods are restricted to use parameters that are generated at runtime. For example,
when we use,
SEL selector = NSSelectorFromString(#"stopProgress");
Its allowed, but
when we use,
SEL selector = NSSelectorFromString(#"%#", runtimeFunction);
Its not allowed!
The app store notice told you exactly what the situation is.
The functions in question are not banned. What is banned is using those functions to circumvent the app store review process and do things like call private APIs or download and execute code. App store apps are required to have all of the code that they run compiled into them. They are also not allowed to use private APIs from iOS. If an API isn't documented, it's off limits.
My guess is that you know exactly what they are talking about, and you are trying to bypass the rules.
If you are not calling private APIs, downloading scripts and using performSelector to call them, then you should submit an appeal to the app review board, explaining what you are doing, in detail, and how it is not a violation of the app store guidelines. If you're truly not breaking the rules and have a legitimate reason for what you're doing then you will very likely be able to get your rejection overturned, but you will need to offer full disclosure and a compelling argument as to why what you are doing is not breaking Apple's rules.
Their field, their ball, their rules. If you're not willing to play by Apple's rules your only real alternative is to try to distribute your app for jailbroken devices, but that will likely cost you your developer program membership.
EDIT:
Based on your comment below, it sounds like the problem is that the framework Rollout.io that you're using is doing js injection, which Apple now bans. I suggest searching on "Rollout.io iOS app store ban" or similar.

What is the best way of implementing App Transport Security?

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

Are performSelector and respondsToSelector banned by App Store?

My latest build was accepted into the Apple app store, but I got the notice quoted below a couple of days later.
My app also uses Rollout.io, and I asked explicitly if this was the problem. No response yet.
If respondsToSelector or performSelector are banned, are there any replacements?
Dear Developer,
Your app, extension, and/or linked framework appears to contain code designed explicitly with the capability to change your app’s behavior or functionality after App Review approval, which is not in compliance with section 3.3.2 of the Apple Developer Program License Agreement and App Store Review Guideline 2.5.2. This code, combined with a remote resource, can facilitate significant changes to your app’s behavior compared to when it was initially reviewed for the App Store. While you may not be using this functionality currently, it has the potential to load private frameworks, private methods, and enable future feature changes.
This includes any code which passes arbitrary parameters to dynamic methods such as dlopen(), dlsym(), respondsToSelector:, performSelector:, method_exchangeImplementations(), and running remote scripts in order to change app behavior or call SPI, based on the contents of the downloaded script. Even if the remote resource is not intentionally malicious, it could easily be hijacked via a Man In The Middle (MiTM) attack, which can pose a serious security vulnerability to users of your app.
Please perform an in-depth review of your app and remove any code, frameworks, or SDKs that fall in line with the functionality described above before submitting the next update for your app for review.
EDIT:
Apple forum mentions this: https://forums.developer.apple.com/thread/73640
It is not respondsToSelector:, performSelector: that are banned. The ban is on putting dynamic content as a parameter to this method. For example, this is not banned:
if([self.delegate respondsToSelector: #selector(myDelegateMethod)]) {
[self.delegate performSelector: #selector(myDelegateMethod)];
}
However, this code might be banned:
NSString *remotelyLoadedString = .... (download from your backend)
[self performSelector: NSSelectorFromString(remotelyLoadedString)];
On March 8th 2017, Apple warned all the developers of JS injection. This includes libraries like:
JSPatch
Rollout.io
AMapFoundation as it includes JSPatch [edit: they now provide a new version without it]
Bugly as it includes JSPatch [edit: they now provide a new version without it]
GTSDK as it includes JSPatch [edit: they now provide a new version without it]
...
If you are directly using a service like JSPatch or Rollout.io, you should stop using it.
If you are using a third-party that was depending on JSPatch indirectly, you should request an updated version of your third-party that does not include JSPatch anymore.
dlopen
dlsym
respondsToSelector
performSelector
method_exchangeImplementations
Sometimes some people used to think all above methods are banned but the exact issue is, those methods are restricted to use parameters that are generated at runtime. For example,
when we use,
SEL selector = NSSelectorFromString(#"stopProgress");
Its allowed, but
when we use,
SEL selector = NSSelectorFromString(#"%#", runtimeFunction);
Its not allowed!
The app store notice told you exactly what the situation is.
The functions in question are not banned. What is banned is using those functions to circumvent the app store review process and do things like call private APIs or download and execute code. App store apps are required to have all of the code that they run compiled into them. They are also not allowed to use private APIs from iOS. If an API isn't documented, it's off limits.
My guess is that you know exactly what they are talking about, and you are trying to bypass the rules.
If you are not calling private APIs, downloading scripts and using performSelector to call them, then you should submit an appeal to the app review board, explaining what you are doing, in detail, and how it is not a violation of the app store guidelines. If you're truly not breaking the rules and have a legitimate reason for what you're doing then you will very likely be able to get your rejection overturned, but you will need to offer full disclosure and a compelling argument as to why what you are doing is not breaking Apple's rules.
Their field, their ball, their rules. If you're not willing to play by Apple's rules your only real alternative is to try to distribute your app for jailbroken devices, but that will likely cost you your developer program membership.
EDIT:
Based on your comment below, it sounds like the problem is that the framework Rollout.io that you're using is doing js injection, which Apple now bans. I suggest searching on "Rollout.io iOS app store ban" or similar.

Does iOS "app transport security enforcement“ mean I need to switch APIs to https?

I am now watching wwdc and saw this. Does it mean all api that I am using should already become htpps?
Also, in my info.plst, I put "Allow Arbitrary Loads" as YES. Do I need to remove and support https?
The short answer is: Yes. All your APIs should use https from the moment on Apple enforces this. (They announced this moment to be the January of 2017) Apple will enforce this in the future but they postponed the enforcement to a date yet to be announced.
Your exisiting apps in the store will still work but you can not submit new apps that do not comply to ATS.
Allow Arbitrary Loads will definitely lead to a rejection then but you shouldn´t already use this today for your production app and rather use exceptions per domain.
Apple also announced that there will still be exceptions for servers that are not under your control. You can mark them as Third party exceptions with the help of the following entries in your plist file:
NSThirdPartyExceptionAllowsInsecureHTTPLoads
NSThirdPartyExceptionRequiresForwardSecrecy
NSThirdPartyExceptionMinimumTLSVersion
But there is no insurance that Apple will accept these servers as third party exceptions and therefore accept your app.
Here is some more information about the topic.
Hope this helps!

Resources