Hot code push crackdown

Later in the day on March 7,  iOS app developers got this notification from Apple when submitting apps, asking them to make changes before resubmitting apps if they are using hot code push technology or SDKs.

This does not affect existing apps on the app store.

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.

App Store Review Guidelines, section 2.5.2 under Software Requirements states

2.5.2 Apps should be self-contained in their bundles, and may not read or write data outside the designated container area, nor may they download, install, or execute code, including other iOS, watchOS, macOS, or tvOS apps.

The Apple Developer Program License Agreement (warning pdf), section 3.3.2 states (underlined for emphasis)

3.3.2 Except as set forth in the next paragraph [the “next paragraph” relates to macOS plugins and extensions and not shown here], an Application may not download or install executable code. Interpreted code may only be used in an Application if all scripts, code and interpreters are packaged in the Application and not downloaded. 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. 

This means:

  • For non-interpreted code, apps may not download or install executable code.
  • For interpreted code, apps should be self contained in their bundles and may not download and execute external code, for example Javascript, except when using the Webkit framework (which uses JavascriptCore internally) or JavascriptCore directly via the JavascriptCore.framework.

The timing of this crackdown

On Tuesday 7 March 2017, WikiLeaks began its new series of leaks on the CIA, code named “Vault 7

Here is the iOS section of the WikiLeaks.  This most likely started the crackdown.

As an example, searching on google for JavaScriptCore on the site gives almost 40 results.

Changing implementation at runtime

  • method_exchangeImplementations: is the basis of method swizzling.  It is used by every major library and a number of apps to switch implementations that are contained in the app.  Apps that have a valid use of method_exchangeImplementations() aren’t affected by this Apple change, specially those that aren’t swizzling to downloaded code.
  • performSelector: is essentially late binding to code.  If the code is in the app binary it is ok.  If it is downloaded it is not.
  • dlopen() and dlsym() are used to open a library for use, and lookup symbols for execution respectively.  Once you load a library dynamically and find the symbol you want to call you can execute it.  Again, if the library is in the app binary it is ok.  If it is downloaded on the fly at runtime it is not.

Reality

Apps have been using third party libraries to download and execute code to change behavior of apps.  Developer apps are being rejected by apple. See this apple developer forum.

React Native has the ability to change the whole app remotely.

Microsoft Codepush also allows publishing JavaScript, HTML, CSS and image changes directly to an app.  Here is the Code Push module for React Native.

Live Game Ops, Live Ops allow games/apps to be changed on the fly.

Man in the middle attacks, security & privacy

Executing Javascript that is downloaded and executed is at risk of Man in the middle attack, where a third party can change the javascript being downloaded midway. This is what Apple is pointing to as the reason of crackdown.

 

Apple should eventually allow Javascript downloads and execution but with added security to minimize MiTM attacks.  Some considerations could be:

  • Require App Transport Security TLS/HTTPS (which was recently relaxed but we expect it to be enforced now)
  • Require HTTP Strict-Transport-Security header,  which lets web site inform the app or browser that it should never load the site using HTTP and should automatically convert all attempts to access the site using HTTP to HTTPS requests instead.  This reduces MiTM attacks
  • Use Certificates and consider using Public Key Pinning Extension for HTTP (HPKP) which is a security feature that tells a web client to associate a specific cryptographic public key with a certain web server to decrease the risk of MiTM attacks with forged certificates
  • Use Public-Private asymmetric encryption between app and server to encrypt downloadable code.
  • Establish explicit trust between the app and the javascript source similar to improvements seen when we moved Beyond Deep Linking to iOS Universal Links (and Android App Links), where, the website uses apple-app-site-association in the root or preferably  .well-known subfolder of website, and the app has to add the applinks: in the app capabilities section in Xcode.

So,

Changing subtle app behavior based on users may not be a bad thing.  Apple is focusing on “significant changes to the app’s behavior compared to when it was initially reviewed for the App Store”

We should hear more about other platforms and apps that get affected by this Apple crackdown in the coming weeks.  I’ll update this blog as I learn more.

 

Posted by Dickey Singh

Dickey Singh is the CEO and co-founder at Pyze and has over two decades of experience in mobile, Big Data and SaaS. He started Pyze to help app publishers engage, retain and grow their mobile users using automation. https://twitter.com/DickeySingh Get Pyze: https://pyze.com