1

My application is build using Flutter, then after we had some penetration tests. Result is received, one of the security risk is about:

No IPAPatch Protection Found

Security reason, I need to prevent my app from being patched by IPAPatch. This case is non-jailbreak IPA Patch. Because, I already put code to detect jailbreak.

I had some difficulties to find a way to programmatically detect IPAPatcher. I have had google and research them, but still didn't find the programmatical way, either natively in Swift or Flutter.

Is this actually possible, to prevent my app from being modified/patched by IPAPatch or at least there's a way to detect the IPAPatch?

  • The problem is you can never really trust code that is executing on a device that you don't physically control. One trivial check is to check the bundle identifier; IPAPatch will change this since the attacker needs a new provisioning profile and they can't use your bundle id. Of course the attacker can also find your code that checks the bundle ID and *patch that*; It is a bit of an arms race. – Paulw11 Jun 05 '20 at 07:21
  • @Paulw11 By that means would be the best way I can see to prevent the mod version app is to add hash checksum in the backend, the hash is from the source code, then make the logic to check that hash with backend version. This is what I can see as the best way to prevent fake app accessing backend, since hash will change when source code changed. – Dhanial Rizky Wira Putra Jun 08 '20 at 10:31
  • That won't really work, because if you use bitcode, the bundle checksum will change. And again, you can't trust the device so the attacker can just patch your code that checks the checksum to always return success. If you are going to send the checksum to the backend then you need to mitigate against replay attacks – Paulw11 Jun 08 '20 at 10:33
  • Would you have suggestions secure way a backend to recognise if the request is coming from patched app or not? – Dhanial Rizky Wira Putra Jun 09 '20 at 05:58
  • 1
    You can't really. You can use an obfuscated signature generation function and secret key to add an authenticator to your message (or include it in a header) but that will only slow down a truly determined attacker. – Paulw11 Jun 09 '20 at 07:50

1 Answers1

0

This is from my app which is written in objc, you can easily rewrite these methods in swift if you’d like.

Check if provisioning profile exist. Apple strips this out when uploaded to the App Store but when sideloaded it remains

   NSString *provisionPath = [[NSBundle mainBundle]] pathForResource:@"embedded" ofType:@"mobileprovision"];

if (nil != provisionPath) {

    // app is cracked..

} 

Verify the apps bundleIdentifer. When sideloading apps on newer iOS versions it will modify the bundleidentifier

NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];

 if(![@"com.yourcompany.yourapp" isEqualToString:bundleIdentifier]) {

 // app is cracked

}

Check for CydiaSubstrate or Substitute. Usually when sideloading apps you will also either inject CydiaSubstrate or Substitute for tweak compatibility.

int max = _dyld_image_count();
for (int i = 0; i < max; i++) {
    const char *name = _dyld_get_image_name(i);
        NSString *names = [NSString stringWithUTF8String:name];
        if (([names containsString:@"CydiaSubstrate"] || [names containsString:@"substitute])) {
           // app could be cracked or user is just jailbroken 
        }

For more methods like checking the encryption state you should check out this thread: How do I detect if an app has been cracked without examining the SignerIdentity? and also don’t think that these methods can’t be broken because they are quite trivial but a good start to protecting your app (: