ios app security

Is the application installed from a trusted source?

This post begins the series of mobile application security. Information on this subject is sometimes difficult to find, does not fully cover the topic, or is incomprehensible or leaves further questions. Based on my experience, I will try to share everything I have learned in this field.

Ok, let’s start then. To begin with, let us consider why we need the security mentioned in the title.

Imagine you have created a banking application. A bad guy appears, who comes up with the idea to try to confuse the user who has your app – he managed to get the source code and create an identical application with a self-signed certificate, and this app will be loaded onto the victim’s device.

While device and operating system vendors have certain control over the applications installed on the mobile device, the end users always have the option to install (also referred to as “sideloading”) applications from non-vetted sources (for example, via USB, received as an e-mail attachment or downloaded from a file-sharing site). Applications sideloaded from untrusted resources are often packed with malware and request (from the end user) elevated privileges, allowing it to access sensitive information stored on the device or hijack end-user interaction with legitimate resources.

In your case (a banking application) it could be, for example, an attempt to steal bank card details.

It is worth mentioning that a separate component is created for banking applications, this is 3DS SDK framework, which performs additional card authorization and also provides many security safeguards.

So, to ensure that the app was not sideloaded, the 3DS SDK should perform checks and one of them is to determine whether the application was installed from a trusted app store. 

Licenses for such libraries cost a lot, and the creators are reluctant to share the knowledge contained therein.

You might as well create and use a similar framework for any application, or implement security directly in the application.

And to the point, how do I implement the above security?

I personally assume that the App Store is the only trusted source (I don’t think this needs to be explained).

In order to clearly identify app source you should verify the following conditions:

  • presence of a mobile provisioning profile – a clear indicator for Ad-Hoc distribution (if an embedded.mobileprovision file exists, the .ipa file is not from the Apple App Store)
Bundle.main.path(forResource: "embedded", ofType: "mobileprovision") != nil
  • App Store receipt data file analysis – the receipt always exists in the app if the user has downloaded the app from the App Store (in the sandbox, if the app has been installed using Xcode or Testflight, there will be no receipt until a purchase is made or restored)
FileManager.default.fileExists(atPath: Bundle.main.appStoreReceiptURL.path)
  • sandbox receipt data file analysis – present when app has been distributed via TestFlight
appStoreReceiptURL.lastPathComponent == "sandboxReceipt"

Considering the above, we can easily check if the application actually comes from the app store:

    enum AppEnvironment {
        case appStore
        case testFlight
        case other
    }

    /// detected environment from which the application was installed
    var currentAppEnvironment: AppEnvironment {
        if emulatorChecker.isRunningInEmulator() || hasEmbeddedMobileProvision() {
            return .other
        }

        if isAppStoreReceiptSandbox() {
            return .testFlight
        }

        if isAppStoreReceiptAvailable() {
            return .appStore
        }

        return .other
    }

Of course, someone may say that an attacker can modify, remove the code responsible for this check (i.e. violate the integrity of the code).

This is true, but here comes another check, the run-time integrity check, which we will cover in another post.

Leave a Reply

Your email address will not be published. Required fields are marked *