As a follow-up to this question, I am trying to figure out what stops Google from modifying our apps that it signs and distributes. Regardless of whether we distribute an APK or an App Bundle, the App Signing service strips away whatever signature that we have and Google signs the APKs that it distributes. In the case of the App Bundle, this will result in several APKs, akin to what bundletool generates.
But since an APK is just a ZIP archive with compiled code and resources, it seems as though Google could modify that as they see fit before signing, including adding or replacing code.
Google has stated:
we don’t modify and distribute your application code without your knowledge and approval
and:
As stated before, Play will not modify the functionality of your application without your knowledge and approval.
Notably, Google used "don't" and "will not"... as opposed to "can't" and "cannot". In fact, in the same post, we see:
For apps uploaded as app bundles, we will improve this security by introducing what is called a source stamp. This source metadata is inserted into the app’s manifest by bundletool.
So, we know of at least one modification, albeit to metadata.
Plus,
the Amazon AppStore for Android modifies APKs before re-signing them:
Regardless of whether you choose to apply Amazon DRM, Amazon wraps your app with code that enables the app to communicate with the Amazon Appstore client to collect analytics, evaluate and enforce program policies, and share aggregated information with you. Your app will always communicate with the Amazon Appstore client when it starts, even if you choose not to apply DRM.
Amazon removes your signature and re-signs your app with an Amazon signature that is unique to you, does not change, and is the same for all apps in your account.
Amazon has been doing this sort of thing for a decade.
It seems as though Google should have the same technical capability as does Amazon.
So, is there anything that I am missing that prevents Google from adding to or modifying the code in APKs that it re-signs and distributes?
Google doesn't just have the capability to modify .apk files uploaded to it's Google Play signing program- they already are.
Granted, this is at the moment a minor change and certainly a non-malicious one; but it remains an actual change of your .apk. They add
<meta-data
android:name="com.android.vending.derived.apk.id"
android:value="1" />
to the AndroidManifest.xml
Below is a comparison that I made in 2018 while researching this topic. It has the apk before upload (signed with upload key), and the apk as downloaded from Google Play with Google play signing enabled.
As you can see from this graphic; there's only two changes- the old signing (upload key) was removed, and replaced with Google signing. And also the AndroidManifest.xml was slightly appended (with the meta-data mentioned above)
I'll also point out this Google IO video from 2017 where they're introducing Google Play signing: https://www.youtube.com/watch?v=5tdGAP927dk&feature=youtu.be. From 11:25 in they're talking about something called "App signing + optimizations". The idea was that they could optimize apks for you, and generate sub-apks.
This was something that you could enable on a per-apk basis within Google Play. Today of course, you'll find no mention of any of this in any documentation, other than in this video- That's because they later came up with app bundles and essentially moved all this work into that. So, this is mostly relevant because the question was "What Stops Google From Modifying Our APKs That It Signs Via the App Signing Service?", and this shows that even specifically for .apk files they can; they intended to; and they were.
As others have pointed out; whoever has the signing keys and access to the Google Play account for the given app- can upload any .apk or .aab containing anything; as long as the packageName remains the same, and versionCode is incremented by one. The same applies of course to Google when Google Play signing is enabled. If they wanted, they could change, remove or add to any and all parts of the application.
It's worth keeping in mind that while yes; Google could modify everything and anything within the Google Play signed .apk file(s), those modifications aren't necessarily evil or with a bad intent. Whether for optimization purposes, compatibility or hot-fixing; there are plenty of reasons Google could or would modify the uploaded apk and justify those modifications. And they wouldn't necessarily warn the developers about this; nor would developers necessarily react to a discovery of this with an outcry.
I do believe that we're very unlikely to see Google perform purposely malicious content changes to uploaded apps, mostly for business, reputation and ethical risks outlined well in the other answers here already. I just can't picture this being a valuable attack vector for Google that outweighs the rather heavy cost-risk, and considering the other, often stronger vectors available to them.
Lastly, I'll mention integrity checks as one way this would be discovered. There are several solutions in this space that goes further than signature checks to verify the integrity of the app. Whether app developers roll their own, or use an off-the-shelves solution- these checks typically run during runtime on device to verify the integrity of the apk; comparing against records taken during compile-time or near compile-time. Modifications performed to the apk during transit does get picked up by this, including whatever change Google Play might do.
Disclaimer: I work for a app-security company that performs such integrity checks (any many other checks and verifications) on the apps that we protect. We've had to map out and account for all changes Google Play might do to an app both for regular apk files and app bundles- so we can distinguish between Google Play doing optimizations and a malicious actor repackaging the app.
At some point, the processor needs to be able to read the instructions in your app to know what it’s supposed to do. The operating system itself needs to know what to do with your app.
Ignoring how an app is packaged for a moment, for the aforementioned reasons, it seems to me there is no technical reason why your app cannot be modified by Google or any technical entity that has the knowledge and resources to do so. Let me explain further why:
It doesn’t matter how the app is packaged - the moment the operating system loads the app, you know what the app does. If the operating system did not know how to handle an app, the app would be useless.
You can try to obfuscate it, the way some popular worms tried to hide their purpose, but it really just delays the inevitable. People have been disassembling and decompiling software right from the beginning, that’s why many licenses used to explicitly prohibit disassembly.
Knowing this, it should be apparent that if “Google” wanted to modify your app they could, because even if the package is obfuscated, when the app is ultimately executing you could see what its doing then, document it, and then modify the app as required. They also have all the technical skills and resources to do so.
Let’s step back for a moment:
The purpose of signing something with a signature, is so that one can determine if the copy of the app they have received is authentic - in this case, if the app that an end user has received matches what is on the play store. The purpose being to ensure the copy you have is the same as the one distributed to other users.
You’re asking if there is a technical reason why Google cannot modify the app - no there isn’t. You’ve mentioned yourself that an apk is just a zip file. If your app was signed by yourself, and that same signature was included in the copy of the app that the end user received, then the end user could verify if Google had tampered with your app. But if your signature is stripped, then the user is left with having to trust Google.
Your question is interesting, because it made me think of something else : I guess the context in which you asked your question was “would Google be able to modify the app before distribution”. With modern devices becoming increasingly powerful, what’s to stop the operating system (since a manufacturer can customise their version of android), from modifying the app after distribution, or in future, on the fly while it executes?
I’m leaving this paper here below:
https://www.cs.cmu.edu/~rdriley/487/papers/Thompson_1984_ReflectionsonTrustingTrust.pdf
The reason being it seems this will always be a perennial question, as it’s impossible for human beings to single handedly verify every piece of software in the kind of systems we use today.
I also find it a bit funny that people think that just because source code is available for an app, that it means they can trust the app which is actually running on their device - unless they’ve gone through the trouble of actually examining the app on their device, it technically is possible that the app running on their device is not the same as the source code describes - it could have been modified by both the developer themselves, or the store distributing the app for malicious or accidental reasons.
But trust has to begin somewhere 🤷♂️. In future, with Quantum Computing, maybe the way we do things will change. But again, there are so few of us who actually understand how every piece of a system works, we will still have to place our trust somewhere. Even if we understand something, having the resources to verify it is another matter as well...
so what stops Google from modifying it?
Do they really need to? It’s the developers which create value for Google Play by creating and submitting their apps.
Would you trust Google if they modified your app without your permission? How would it affect your perception of them as a company, since privacy is already a major issue.
In the event that a modification of theirs causes your app to behave incorrectly and cause damage to a customer, yourself or some third party entity, who will be held liable?
The above are just some of the reasons to think about when considering if Google will modify your app. It’s a can of worms. In the end, it boils down to cost-benefit & risk-reward analysis. What would they modify your app for, and is it worth any risk of repercussions?
In summation, there is no technical reason why they can’t. Why they don’t / won’t boils down to their business motivations and model. There is nothing to say why they will or won’t in future. But there is no reason to arbitrarily modify an app - there has to be a valid business reason which results in some kind of gain.
Simple answer: Google can, if they want to. In a digital signature scheme the signer has complete capability of modifying the document prior to signing.
Why they won't: Because developer can easily detect it, and the payload which is of most importance - the classes*.dex, actually containing the code - can easily be decompiled by interested third parties (or the app creator) to figure out any added code. (Adding code into JNI libraries is even less likely). To clarify, the detection by the developer is as easy as unzipping the APK and comparing its contents to what the developer submitted.
The impact of adding code to an app without notifying the developer would likely cause quite a backlash if discovered. Of course, at any further date Google could decide to change their terms of use, migrate from DEX to LLVM bitcode, or do something else, which might change this behavior.
Clarification: It is true, that Google could in theory ship modified apps only to certain targets, but once again it suffices that one such incident be detected (maybe by a concerned app-user mailing his or her APK to the developer?) for the implications to be far reaching for Google.
This, btw, holds true for Apple as well, being the signer of all App-Store apps. In the Apple case it's even more of a question, since apps may get recompiled by Apple (from BitCode to to the underlying ARMv8 variant), and apps deploy encrypted by FairPlay, which makes it virtually impossible to decrypt the app outside a jailbroken device.
As an anecdote, you could wonder if a malicious device vendor couldn't change dex2oat (the on-device compiler) to inject arbitrary code when the app is installed and compiled on the device itself. This would be much harder to detect, since on a non rooted device there would not be an easy way to access the compiled art/oat files of the app. But then, malicious vendors can also directly modify the Android frameworks, as well.
Apologies for potential anachronism here.
When you say
the App Signing service strips away whatever signature that we have
are you sure this is what it does? One could imagine an alternative scheme, which could achieve everything noted in other answers / comments as actually occurring:
Assume that the dev has uploaded their artefacts (let's say as an .obb) and signed it using their upload key. Google appends its additional metadata (think of it as a kind of diff file) and re-signs the resulting expanded payload. On receipt at the device, android checks that the payload it has received was correctly signed by Google (which it was), removes (but keeps) the metadata Google added, then checks the remaining payload (the dev's .obb) against the dev's signature. If that checks out, which it presumably will, it applies the change implicit in the added metadata to the original .obb
That .obb becomes the artifact which android installs. It isn't what the dev uploaded.
Google hasn't stripped the dev's upload signature, they've just added extra payload in a way which doesn't invalidate the original signature, then added some more payload and a signature of their own.
I'm not saying this is what they are doing, just that this is what they might be doing. You would be able to detect this once you had downloaded the payload and installed it on a device. Could it be made to happen or not according to which device the download was sent to? I expect that wouldn't be hard. And in that case, you wouldn't be able to detect it unless you had access to a device which had been targetted for the modification. It would be very difficult to detect the modification process while it was occurring. You could tell the difference between a modified payload and an unmodified payload immediately on receipt at the device because the presence or absence of the metadata "diff" would change the file size.
I don't know whether bundletool could support such a scheme. I guess that's where you could look for clues.
They may just be stripping the dev's upload signature and replacing it with their own. The only protection against signature stripping comes from checks done by the receiver.
When it comes down to it, you cannot trust any crypto scheme if you might consider the receiving endpoint to be compromised. Whether the payload is encrypted (which in this case it isn't) or merely signed, if the endpoint is not going to enforce the scheme, the sender and the user are both potentially exposed.
Technically, in this case, the crypto on the endpoint is in the control of the device manufacturer, although it is questionable whether they would actually exercise that control against the will or interests of the OS provider - Google - assuming that manufacturers even check these things.
I have signed my APK now but if I open it up I can still see many things like websites I connect to, Stuff that is written in the APP etc. Is there anything that I should be aware of? On one hand this is needed to run the app, but is there any sensetive data included?
proguard doesn't obfuscate strings. Dexguard does, but you'll have to pay for it.
We are developing an Android application. We know that using tools like APKTool, dex2jar can get the source code of an APK.
1) Can they get complete source code so that they can rebuild the same APK, with very minimal effort?
2) After getting the source code, is there a possibility that others can upload the rebuilt APK under their own name?
3) If possible, how to prevent this?
Our clients are keen about this.
It is not possible to prevent your application from being reverse engineered. However, you can make it harder using tools loke proguard.
Yes, it is possible that others can upload the reverse engineered APK. Nevertheless, they need to change the package name.
It cannot be prevented.
Have a good look here for a more detailed explaination: How to secure my app against piracy
1) They can, but NOT WITH A MINIMAL effort.
2) Sure, they can.
3) You can't. You can just make their work a bit harder, trying to obfuscate your code as much as possible and crypting your dbs (which is the most important thing you and your users should worry about).
Not sure what you mean by APK? You can certainly extract and decompile an apk, repackage and resign. It would be the same but would have a different signature and so couldn't be installed over the an existing installation. I'd argue this can be done with minimal effort using Apktool there 100's of articles on how to do it. But even easier with APK2Java which turns converting apk to java into a point and click experience.
Yes, to other appstores with no code changes. If the attacker changes the package name which is simple there are automated scripts that can so this it could be uploaded to Playstore.
100% preventable?, no. But you can make it allot harder and raise the difficulty and effort level required. As others have mentioned Proguard is a good start, I recommend Dexguard it's not free but really adds to your apk hardening. You could also add tamper checks to break functionality or alert user.
I've talked about Android app hardening at Droidcon UK here's the slides they may help. The idea is to add several levels of security to raise the time/effort it takes so most attackers will just move on to another app.
Looking to improved the security of my Android app to flag if the .apk has been extracted, modified, repacked and resigned. Here's article from Zdnet noting the issue link1.
The concern is if the app is targeted by hackers they could add malicious code and upload to an alternate app store and dupe users in to downloading it.
So I'm thinking code to verify a checksum of the apk or signing certificate?
I appreciate the app code could be repacked and any security code removed, but it does increase the difficulty of repacking it, maybe enough for them to try another app.
[update]I know the Google Play store licensing module offers something similar but I'm looking for something for non paid apps and other/non marketplaces.
I ended up using Dexguard (paid obfuscator for Android). It offers a module that preforms apk verification. It is simple to implement and offers better than average protection.
Here's the code to do the check:
dexguard.util.TamperDetection.checkApk(context)
The main issue is where to store the checksum of the apk to verify against given that it could to be replaced. The dexguard way is to check it locally but using other features like class/string encryption and api hiding obscure this call.
Here are some of the articles that could help you out.
Retrieving APK signature during runtime.
Self checking an APK signature.
How to check APK signature.
Use the Google licensing service It will connect with the play store to make sure the user purchased the app every few days. (you can set the amount) Also loook at ProGuard. It strips all the class, method, and variable names out of your code making it really hard to understand once its decompiled.
I've just released an app, a paid app, 4 days later a user told me there's another web site in China hosts my app. I downloaded it from there, and it does run fine on my device!
There are posts here saying people can change the package name and republish an apk. But this is not my case, the cracked version still uses the same package name. I used Android Vending Licensing in the program, but the cracked version does not do licensing check at all. I used ProGuard to obfuscate it, but that doesn't discourage the hackers.
Question #1: I signed the apk file according to Google's instructions. But still, they modified the code and took out the licensing check part. Am I wrong that signing an apk file is designed to keep people from tampering with the file content?
Question #2: For Win32 .exe programs, I used to use a checksum to determine if the file has been altered. This is how it works: When a .exe is created, I used a tool to calculate the sum of byte contents of the file, then stuff it into somewhere in the file, for example, 4 bytes after a text pattern "MY SIGNATURE". Then at run time, the program opens the .exe file and calculates the byte sum, compares it with the integer after the signature.
Has anybody tried this approach on apk files? Care to share your experiences?
Ultimately the built in protection of apps in Android is very poor. Here are your best practices.
1) Yes Google's recommendation to use code obfuscation, signed coded, and their license verification server is designed to prevent software theft. Their implementation however is highly flawed. The only requirement that an APK has to run is that it be signed. It doesn't matter who signed it though. There are no checks that your signature is the one it's signed with. So to crack it you just remove the license check and re-sign with whatever cert you want. Then a user can load it on their phone with "allow non market apps" checked.
Don't use Google licensing as is. Modify the code heavily. Add some new parameters to use when generating the keys. Move the code around / re-architect it. Don't include the Google licensing library as a library project. Put it directly in your code. Make the code as spindly and kludgy as possible. Add functions that do nothing, but modify the values on the fly. Make other functions later that convert them back. Spread license verification throughout your entire code base.
If you don't do those steps then the code can be cracked automatically. By doing those steps at least the cracker needs to take the time to hand crack it. That would probably only take a few hours at most. But a few hours is much much more time than instantly cracking the standard Google licensing layer. There are cracker tools that will actually just auto-download newly released android packages and, if they use the standard android licensing, crack them and upload the cracked APKs to these types of web sites. By making your implementation not the vanilla implementation you make things much harder, with only a few hours effort on your end.
2) This is a common anti-crack technique. You can do this on Android if you want. But it can be cracked in about 5 minutes. If you Google there are tutorials on how to crack this specific technique. Basically you just look for the CRC call in the code and remove the check after the CRC comes back.
Android has no inherent security. You can root any phone and download the APK. You can easily hack an APK to enable debugging and simply step the code to see any keys you have stored in the code. So in the end I wouldn't spend too much time on this. It's impossible to secure an Android App. I would just do the common sense stuff in the list above and move on.
3) If you're really paranoid you can implement your own licensing on your own licensing server. This is the approach I took, but not as much for protecting the app for theft, as it was to give me a mechanism to sell apps directly from my website so users that don't have Google Play could still purchase my apps.
Passive/Aggressive Scuttling
I agree with #metalideath that obfuscating and cludging the licensing code is not foolproof.
Here is an easily hidden technique I call 'scuttling' that works for apps deployed to Google AND Amazon. Scuttling is front-end piracy detection by the app. What to do once detected is in the purvey of the app creator.
Aggressive Scuttling: Eg. Termination and/or alarms on pirated app. Network communication not necessarily required.
Passive Scuttling: No app modification. Eg. enable tracking.
Passive/Agressive Scuttling: subtle app modification. Eg. silently disable key features. Lead pirate into thinking they bungled, and into unpublishing the pirated app.
If your app was renamed and/or installed from any source other than Google or Amazon, scuttle() returns true.
// Dont just copy/paste this code - that is what automated crackers look for - cludge it!
// No network communication is required at runtime.
// myPackageName should decode at runtime to "com.yourpackagename"
// google should decode at runtime to "com.android.vending";
// amazon should decode at runtime to "com.amazon.venezia";
public boolean scuttle(Context context, String myPackageName, String google, String amazon)
{
//Scallywags renamed your app?
if (context.getPackageName().compareTo(myPackageName != 0)
return true; // BOOM!
//Rogues relocated your app?
String installer = context.getPackageManager().getInstallerPackageName(myPackageName);
if (installer == null)
return true; // BOOM!
if (installer.compareTo(google) != 0 && installer.compareTo(amazon) != 0)
return true; // BOOM!
return false;
}
RESULTS
The following screenshot was taken from google analytics showing a pirated tracked free app from playstore (com.android.vending) that was redeployed with aggressive scuttling (non-playstore installs detected and terminated). Non-playstore (not-set) tracking drops. Tracking was not required, but enabled for these measurements.
DISCUSSION
Note service signing plays a role in scuttling: The package manager enforces unique package names with unique signatures.
This presents the question of what to do when the app is scuttled (pirate detected by the app). Piracy is a form of viralization (uncontrolled distribution) of your app. It is already detectable by enabling the analytics tracking back-end. Scuttling allows the app creator to customize a front-end response with or without tracking.
Aggressive scuttling is obviously detectable by pirates (BOOM!). This encourages further cracking. Passive scuttling is far less obvious, but may involve tracking.
Piracy may not be preventable but it is predictable, detectable, and trackable.
Tracking can present insurmountable problems to pirates, but also presents it's own ethical issues.
Passive/aggressive scuttling requiring no network communication as outlined above is perhaps the best solution. It is easily hidden (unlike licensing) and can be tailored to be as unobvious as possible.
The best thing to do is not worry about it. The people pirating it in China are not your customers, and never will be. If there was no pirate version available they still wouldn't pay you for a copy, in all probability. Besides which if your app becomes popular it will be cloned anyway, just like iOS apps are. The security systems you have already implemented are all that you need as they prevent most users from pirating the app.
Trying to make your app piracy proof will just harm the code base and make it harder to maintain, as well as potentially introducing problems for your genuine paying customers. Instead focus on promoting your app and making it easy for customers to pay for and use. By being responsive to feature requests and bug reports you add value that people are willing to pay for, rather than seeking out some dodgy cracked copy from a Chinese web site that is probably a trojan anyway.
Finally, report the pirate copies to anti-virus vendors. Supply copies of the APK. They will add signatures to their databases so that it gets flagged up as potentially dangerous.
My understanding from reviewing the Google market terms is that you cannot sell your app directly from your own site as it violates the Google app market terms. I think that implementating custom protections in your code is the best way to go. Standard methods just are not effective since code can be easily dissassembled