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.
Related
I have a problem when pushing my iOS App to the App Store. I know this is not a coding issue.
I got rejected because of guideline 2.1 that the App Store wants to test full features of my app. There are parts of features that they are unable to reproduce (e.g. OTP code, product code ,etc).
What does it mean by providing built-in demo regarding the 2.1 guidelines? How can I make it?
Added to 2.1: “If you are unable to provide a demo account due to
legal or security obligations, you may include a built-in demo mode in
lieu of a demo account with prior approval by Apple. Ensure the demo
mode exhibits your app’s full features and functionality.”
My apps never got rejected. You can use the form where you can put comments to the reviewer into how to create an OTP entry, for instance, like, use this seed, and provide the seed. Remember the QRcode are only a convenience to provide the seed. Try a seed like 123456 depending on the algorithm the length may vary. Just inform how they can view this feature working. It's very simple actually. I cannot see something that you cannot communicate previouslly to the reviewer... if was a network access, provide a temporary APIKEY or better, a demo account. You can always remove later.
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.
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.
I want to display a view on call screen of iPhone and get info comming call but I can't.
I found one link access private API but it saying that apple will not approve this,
But i saw some application on appstore.
Link
https://itunes.apple.com/au/app/contact-notes/id660212820?mt=8
Can any body tell me how to do this?
You may have luck using the APIs in the new CoreTelephony framework Apple added, specifically the CTCall class. This doesn't reveal the caller, but it may be possible to somehow get that.
Using private APIs in any way is not recommended and will break on future releases of the OS, and it's doubtful if you'll even get in the App Store using them. Don't do it.
It's possible that the application you cited as an example uses these private APIs, seeing as it has iOS 5 compatibility. If you really need to use that API, it's possible to obfuscate your use of it with method swizzling, or getting function pointers and calling those, although that can will break when Apple changes their private APIs.
Lastly, you could download and install this app, then dump its symbols to see what APIs it uses.
I know UIGetScreenImage is a private api, and in a period time can use in the appstore.
and later someone said can't use anymore.
So I ask here to make sure, Can use in my app and pass to Appstore?
Best Regards
Take a look at this Apple tech note. It shows how to "legally" do screenshots in UIKit where it will get accepted into the App Store:
http://developer.apple.com/library/ios/#qa/qa1703/_index.html#//apple_ref/doc/uid/DTS40010193
They have been rejecting it again for a long time, since iOS 4 release in 2010 when they introduced AVFoundation framework which was a solution for all the camera frame capturing that UIGetScreenImage() was mostly used for before.
They offered two alternatives, one for camera frames (Technical Q&A QA1702) and one for UIKit elements (Technical Q&A QA170 - the one that Michael mentioned), but neither of those is nearly enough usable for taking actual screenshots.
You can read the announcement at developer forums (iOS Developer Program account required).
Around a year ago, Apple started to run static analysis on submitted binaries during the App Store review process. Before that, access to private APIs will pass the review if the functionality itself wasn't too obvious to be caught by the reviewer.
Currently, reviewer uses automated methods to identify private APIs by their names. I recall reading somewhere that, not only aren't you allowed to call them, but also can't you use private API names in Category method names. I imagine because the scanning process is automated, you wouldn't have a shot to pass the review if you did use undocumented methods.