We Reverse Engineered 16K Apps
hackernoon.com
hackernoon.com
Make your own damn API. Have it do exactly what users are allowed to do on your behalf. It's not an unnecessary cost, it is 100% necessary if you are interfacing with external services from your app.
Or don't, and get bitten in the ass eventually.
That said, security is not all-or-nothing. And anyone who believes that modern web-connected software can be 100% secure is either misinformed or trying to sell you something that you probably don't need.
https://aws.amazon.com/blogs/mobile/using-the-amazon-cognito...
And they also provide a generic TVM (Token Vending Machine) implementation that you could adapt for other APIs
Note that if the keys are valid for all users, you'd only need to do this once per service.
- Fetch credentials and keys on login and then save them in an encrypted manner in
- SQLite Encrypted DB
- Android Services like KeyStore[1]
- AccountManager lets you save metadata[2]
But the way I mostly end up using which provides protection from a lot of Reverse Engineering Tools(JADX,dex2jar,smali) is:
Use Enums instead of String constants. Using
``` public enum Key {
Key1("keyValue");
String keyVal;
private Key(String keyVal) {
this.keyVal = keyVal;
}
}
```
obfuscates the `keyVal` from many class decompilers.I'd love better ways to do this. But when you do Android development (like when you do Front End web dev), its easier to just assume that everything you wish to keep private will be visible and avoid keeping/saving critical information on the client app.
[1]:https://developer.android.com/training/articles/keystore.htm...
[2]:https://developer.android.com/reference/android/accounts/Acc..., java.lang.String)
At the end of the day it's all security by obscurity and the real answer is proxying calls or TVMs to limit what individual keys can do, but it doesn't hurt not to be the lowest hanging fruit either.
But Twitter API keys? These just allow access to the Twitter API. If these are leaked, the biggest risk is a denial-of-service of rate limits by a third party, which Twitter may catch and revoke the account. The developer will then have to create a new credential and update the app for it to keep working.
In this day and age where mainstream apps update often too, I doubt this is seen as a serious risk, for the long tail of apps. If this approach obviates maintaining Backend-as-a-Service proxy the developer pays out of their own pocket, it can be more cost-effective.
When doing web stuff, I can't trust the client with my api secrets, that's why I use oauth. My secrets are (theoretically) safe on the server side, and the client generates a short-lived token that lets me access services on their behalf if needs be. Google's drive filepicker is a pretty good example of how that works. It's awfully complicated (just logging in requires me to open an extra tab and listen for events on it for when the login flow completes), but it does work as a way to keep me from having to push out secrets to the client.
Doing this right basically requires two things. First, you must make your own API server that can run code on behalf of the client. You can trust the client to ask for stuff off of the API if it's properly authenticated, but you can't trust the client to run its own authorization code - anything that requires authorization rather than authentication has to run on the backend somewhere.
Second, your users have to trust you a little bit, so minimize that trust surface. With stuff like Google APIs, only ask for stuff you really need. I know I'm one of the few people who really read approval screens, but I have rejected and will continue to not use services that ask for too many permissions. Find the ones that just fit what you need (such as drive.file instead of drive), and don't ask for more. Don't ask for offline access unless you really mean it - I'd rather have to go through the flow again if my 30-minute token expired than let you keep a refresh token on your server (but again, the danger of the refresh token is mitigated by asking for the minimum).
1. You now have control over accepting the requests or not (ban ips, etc). If your app is pretty popular, spammers may try to use your app credentials to interact with Twitter as you will have a better reputation than newly generated credentials.
2. If your key is disabled by twitter for abuse, you can replace it with a new one without having to update the app itself.
This applies to the other services too.
> These secrets belonged to a lot of different 3rd party services, for example Uber’s secret which can be used to send in-app notification via the uber app.
In every Apple application - aren't these keys a one off, created by the client?
"The device token included in each request represents the identity of the device receiving the notification. APNs uses device tokens to identify each unique app and device combination. It also uses them to authenticate the routing of remote notifications sent to a device. Each time your app runs on a device, it fetches this token from APNs and forwards it to your provider. Your provider stores the token and uses it when sending notifications to that particular app and device. The token itself is opaque and persistent, changing only when a device’s data and settings are erased. Only APNs can decode and read a device token."
Source: https://developer.apple.com/library/content/documentation/Ne...
If it is only your own token/secret you are seeing, that does not seem so bad, right?
In addition - let's say these apps DO leak secrets, what is the alternative solution here?
You just need the server token, and a phone number to send the notification. (The gsm token already in possession with Uber can be used to send notification to anyone at will)
Here is the uber documentation regarding reminders: https://developer.uber.com/docs/riders/references/api/v1.2/r...
(and ignored on hacker news back then)
https://news.ycombinator.com/item?id=7918649
mostly good to give credit where credit is due.
Also, if services only give you a single secret key per developer, what is the alternative? Proxying all API requests through your servers might work, but only with low-volume and if the service doesn't have rate limits per IP.
Most other schemes would require cooperation from the API providers, right?
If the app uses DRM (e.g. Netflix), I would imagine that some of these laws could apply depending on the country, right?
No paid api (intended to be used by a server instead of an end-user) has rate limits per ip. If it's a free api you are either using it in a way they did not intend, or the api secret is generally not truly secret (granting you special privileges) just a way to identify developers.
As for low-volume, obviously you should have servers to handle the traffic from your app. If you aren't low-volume I'm sure you can afford more servers.
It doesn't feel like you're curious for your own sake. Why are you asking?
Also, anything is illegal somewhere. Where do you want the answer to apply to?
I'm mainly interested in answers for the US, Germany/EU, and Switzerland.