Skip to content

Instantly share code, notes, and snippets.

@antoinevg
Last active March 28, 2017 06:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save antoinevg/c23edf71b77c06cce14e53e9cb39e257 to your computer and use it in GitHub Desktop.
Save antoinevg/c23edf71b77c06cce14e53e9cb39e257 to your computer and use it in GitHub Desktop.

Trigger.IO Statement for App Review

This is a statement intended for reviewers who have rejected customer apps built using the Trigger.IO Forge Hybrid App development platforms.

This statement refers to version v2.5.4 of the Trigger.IO platform and presents the current technical and procedural facts which are current as of 24 March 2017.

Summary of the app technology used to build the rejected app:

Trigger.IO is a five-year old cross-platform hybrid app platform similar to Phonegap/Cordova that allows users to build iOS apps using HTML, CSS and Javascript.

The Trigger.IO runtime, like the Phonegap/Cordova runtime, exposes an interface to the user's Javascript code that allows them to invoke a controlled set of Objective-C methods that provide functionality such as geolocation, client-side notifications and iOS in-app payments.

At no point now, or in the past five years, has the Trigger.IO runtime performed any conversion of Javascript code to native code, made SPI calls or made modifications to the app binary using resources downloaded after compilation.

Why the rejection reason should not apply:

There are a number of reasons which we will cover one-by-one.

1 The allegation: "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."

Trigger.IO provides a mechanism called "Reload" which allows users to ship modifications ONLY to their app's HTML, CSS and JS resources. It can NOT be used to make modifications to either the App binary or the method calls compiled into the App binary.

We believe that the Reload implementation conforms to the exception made in Section 3.3.2 of the Developer Program Guidelines:

"The only exceptions to the foregoing are scripts and code downloaded and run by Apple's built-in WebKit framework or JavascriptCore, provided that such scripts and code do not change the primary purpose of the Application by providing features or functionality that are inconsistent with the intended and advertised purpose of the Application as submitted to the App Store."

Trigger.IO provides no other functionality which can make changes to an app after App Review approval.

Furthermore, Reload functions identically to services such as Microsoft's "CodePush", Ionic's "Live Update" etc. and users of these services have not been impacted by this recent change to Apple review policy.

Nonetheless, wishing to act in the best possible faith, we released a version of Trigger.IO which had all code for implementing the "Reload" feature removed. This is the version used to build the app you are currently reviewing.

Despite this, customers who rebuilt their apps with the new version still had their apps rejected.

2 The allegation: "While you may not be using this functionality currently, it has the potential to load private frameworks, private methods, and enable future feature changes."

Neither Reload nor any other feature of the Trigger.IO platform enables customers to load private frameworks, private methods or enable future feature changes on that basis.

3 The allegation: "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 and/or call SPI, based on the contents of the downloaded script"

At no time in the past or present has Trigger.IO contained code that accepts arbitrary parameters to the dynamic methods listed above in order to change app behaviour and/or call SPI based on the contents of a downloaded script.

During the course of review we only found one invocation of the API methods listed above in our source code.

The invocation in question was a call to respondsToSelector with the name of the method, compiled into the app binary, which a customer wished to invoke from Javascript.

Ironically, this invocation existed only to ensure that customer Javascript is explicitly prevented from trying to access methods which are not exposed by the Trigger.IO runtime.

We have since removed this method invocation entirely but customers who have submitted apps based on this new version of the platform have still had their apps rejected with the same notice. The app you are currently reviewing was built against this version of the platform.

4 The allegation: 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.

Trigger.IO Reload uses https for all Internet communication. The https protocol is specifically designed to foil MiTM attacks.

In an effort to eliminate all possibilities we also tried to submit a test app which:

  • Had the Reload feature entirely removed.
  • Did not access any remote scripts or resources from within the contained HTML/CSS/Javascript code.

This app was also rejected with the same allegation.

5 The allegation: "it would be appropriate to remove any features or functionality which takes javascript script and turns it into native code. This is especially true if the script-to-native-code feature can occur using remote scripts sent in after an app's review is completed."

The Trigger.IO platform has not now or at any time in the past had the ability to take javascript code and turn it into native code.

While JS/Native compilation would enable performance optimizations not currently available to hybrid apps we are also very much aware of the security concerns inherent in any such functionality and have therefore always been content to work within the guidelines set by Apple.

We would welcome any request by the review team for access to the Trigger.IO platform source code in order to establish the veracity of this claim.

6 A reasonable hypothesis: There is a strong possibility that the rejections are being made due to triggering of a false-positive by Apple's tests for libraries such as rollout.io and JSPatch.

The evidence we have that points to this hypothesis is:

  • Being the authors, we have every reason to believe that the Trigger.IO platform is innocent of the allegations made in the rejection notice.
  • Trigger.IO app rejections started on the same day (8th March) when Apple started rejecting apps which contained rollout.io and/or JSPatch en-masse and the rejection notice contains the same text as the rejections Apple issued to users of rollout.io and JSPatch.
  • Some customers with multiple Trigger.IO apps sharing identical binary configurations found some apps rejected but others not. These are so-called "white-label" apps so the only differences between them were the HTML resources used to brand the apps.
  • Some customers who rebuilt and resubmitted their Trigger.IO apps with no modification found their app to be accepted the second time round.
  • Some customers who rebuilt and resubmitted their Trigger.IO apps with no modification found their app to be accepted after they created a new app on iTunesConnect.
  • Repeated review of the Trigger.IO source code showed no relationship between the reasons cited in the rejection notices and our code or any 3rd-party libraries used by our code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment