I'd like to develop a simple Android application that authorizes access to a server in the following way:
The app stores a local counter t_count of access tokens which initializes at t_count = X;
Whenever the user wants to access the server, the app signs a proof that it consumed one token and sends it to the server via a local connection;
Once the machine acknowledges the proof, the app securely decrements the token counter;
If t_count = 0, the app should prevent the user from sending consumption proofs.
The most important here is that the app can only decrement the counter, and only with an associated a signed proof of consumption. No other modifications should be allowed, even if the user has root access. Ideally, this counter should be stored in a TEE-protected environment.
While doing some research I discovered Android supports a TEE-backed key storage that prevents attackers from extracting private keys. However, it is unclear to me whether I can use this functionality to store an arbitrary counter or, if not, what would be the best way to protect it. I don't know how I can securely update and verify the counter either (or even if this is possible). I don't have any background in Android development.
Thanks in advance.
EDIT: I cannot place the counter in the server because in my use case the user can access many servers which are offline. Hence, the easiest way to keep track of the accesses is to manage the counter inside the user's device (if it can be done securely).
What you are trying to do is not possible.
You should never trust a client. From the Server's point of view, it is impossible to tell if it is interacting with software that you developed v.s. software that an attacker developed. Relying on a client to not send "consumption proofs" based purely on a counter that the client has control over is not secure. As an aside, if there exists a way for a client to send "consumption proofs" without actually consuming anything, then it is not a proof of consumption.
If you want to limit accesses to a server, it must be enforced on the server side.
Related
I'm, working on a security scenario for an Android Application to prevent sending unwanted/spam or multi-requests by users.
These users are unregistered and as you know one way to detect them is by checking the IP addresses but the problem is that the public IP Addresses will change. Users can turn On/Off the modem (as an example) to get the new public IP Address or can install/uninstall the app to refresh everything and start sending unwanted requests to the server.
I want to make something like a token and store it on the phone that it will send with their request and on the server-side, we can detect which these requests come from which phone/user and handle the security issues.
This token or ID must have these features:
Access to it (deleting) should be impossible or hard for normal people (not for
hackers, I know it's impossible)
If the app has been uninstalled/installed, Android OS doesn't remove
it
Is it possible?
Is there a better solution to handle this?
The Android developer docs have a good article on available user IDs. Getting the second property will be difficult because Android has been pushing for resettable IDs for user privacy. The firebase installation ID (FID) is close, but you don't get #2. You can also use SafetyNet APIs to see if the app is genuine and then build rate limiting in the client or server side.
I want to develop a GPS-based game (actually part of my game will be GPS-based, but the user will need to be authenticated).
In my back-end, I have entry points for the users collecting the data, so no data will be stored in the client app (at least not game data).
Assume I use a secure communications channel (say: HTTPS or WSS respectively), and the certificates are trusted (say, Startcom SSL... actually doesn't matter as I could focus on SSL providers later). This means: The client application connects to a server and receives its PubKey certificate.
Part of the communication (either by HTTPS, WSS, or regular sockets with TLS layer) will involve the client application send its GPS coordinates. They are sensitive data which will be stored in the server, but the data will be generated by the client.
Q: What technique (or perhaps an already-built-in application available on each Android device since a specific version) could I use to validate that the connecting application is the allowed one?
The problem I want to solve is this: I don't want a player cheating (by using a hacked client application respecting the same protocol of my application) sending a fake/crafted GPS position.
Technologies I will use: (Mainly) Android (perhaps later with other devices but not yet) 4+.
What do I expect: I don't need specific lines of code to solve the problem (althought lines of code are welcome), but focus in a good technique, concept, or complementary tool.
Note: This is not an account authentication problem. It is not about the ability of users to impersonate other users, but a hacked/cheatful client application impersonating a good client application (often by the same user trying to cheat).
there is no way to validate real GPS location in android devices.
I am working on an applikation for Android platform. The application uses heavy amounts of HTTP calls to my webserver. This works out verry well but im in need of assistance in securing my calls and webserver.
I know that i can use SSL through Https to encrypt my connection both clientside and serverside, this is not a problem and will ofcourse be done when launching the application. But what would the most secure way be to have a session for the logged in device?
Ive thought about making a mysql based session system containing the following rows
id - sessKey - sessCont - sessUid - sessTime
sessKey will be a random generated 32 bit key. sessCont a JSON array of the stored informations and sessUid will be the user id of the user signed on. sessTime would contain a timestamp.
This session will be set on login and the phone would then recive the sessKey + sessId. When making calls the key will be changed and returned to the phone again. If a call is 10 minutes later than the latest call the session will close down and a new one will have to be made.
Yet i keep seing ways of compromising this approach, as well as i can with all other approches im able to think off.
How would i manage to make the best possible security and session control from my phone to my serverside script?
Thanks in advance.
Jonas
Alright numbered list time...
If you're using an SSL connection a good portion of security is already on your side. You can cross sniffing off your list of vulnerabilities.
Most of the leftover vulnerability will be on the user end, can hackers monitor the hardware on the user end and grab a session information after it's been transferred to the user's hardware, which in this case is an android phone. App data is protected from other apps so unless you, the developer, or your user is doing something insanely reckless it should be secure.
Which leads me to #3, all the rest of the security really lands in your lap as the developer. If you have cross-site scripting (XSS), the session IDs can be guessed easily, or you are vulnerable to session fixation, or your session ID storage is weak (SQL injection?) then you've effectively undone all the good work you did with every other measure of security.
In the end there are always ways to hack a system, but if you follow those three steps you've done everything you can do in order to prevent hackers. The rest unfortunately lies in the parts we can't touch; Android operating system, cell phone networks, user's common sense.
P.S. The most secure method would probably be to trash the session idea. Store the user id (a number that could mean anything), and a md5 encrypted version of their password. Be sure to add something funky so hackers can't just look up the reverse of common passwords. (IE. theirPassword+userid+HACKTHISSUCKERS) and even if someone goes to an md5 reverser they won't be able to undo your hash. And then every time you make a request to your server, do it over SSL and when the authentication checks out, send the info. Secure SSL connection, secure md5 passhash, no security leaks.
Even if a hacker somehow found what your app was sending to your server; a number and a undecipherable hash. The only way they could find out what your app was sending was if your user was being negligent and allowed their phone to be connected to the hacker's hardware that was actually capable of intercepting POST data before it was sent over the SSL connection.
I came across a few tutorials online explaining how to connect to MySQL from an Android app, but they are a bit surface.
If I just write SQL and send/receive it in a POST, it seems problematic for a few reasons:
1) Hardcoding SQL with obvious issues there
2) Security concerns about sending sql - is that safe to send that request? or should it only be done via SSL?
3) To connect to the db, in order to insert things, I need to have the db connection info inside the app - is that safe? Can the code be read by someone hacking the device and the apps?
What is the best way to go about connecting and using a remote db from an Android app?
Thanks!!
Wrap everything in an API and manage authentication either with encryption with public/private keys or with a token-based system. You should never, ever, ever accept raw SQL in any way, shape or form from any device or site. Most often if you need live, remote data to run you should reconsider your application workflow and work off slightly stale data or provide the information in the background due to the possible spotty connections. Hitting even an API can be a costly endeavor so it shouldn't be something that has to occur frequently.
To incorporate some of the ideas above you could a couple things. For the public/private key read up on http://en.wikipedia.org/wiki/Public-key_cryptography. The basic concept is you store the public key on the device then negotiate a private key after the installation of the application that is also stored on the device (although not coded into the application). This key is the one you have to protect so it should be negotiated on installation and stored with the lifecycle of the application. You could contact an API with a unique hash of the device (say the device ID) and a password that the user could set. In that way if the data is wiped, since the password is stored on the server you can validate that a request to generate a new key is valid for that device ID and also protect against attackers trying to disrupt everyone's keys.
Obviously this is still susceptible to someone intercepting the initial request but if you are using HTTPS (which you should) then it should mitigate most of these issues.
You have to make sure an attacker just cant send in random device ID requests to generate new keys as it would disrupt the actual user's device of that hash, which is why the password set is important. Of course they could also do this against device IDs not currently registered but you could easily implement throttling and blacklisting against the initial API.
There are many things you can do but depending on your sensitive data it may be overkill. You'll have to make that judgement call and figure out who you are trying to protect your data from.
Use a webservice through which to communicate with the database. End User clients generally do not communicate with the database over the internet. Multitier_architecture
I'm building an Android application that needs to communicate with a MySQL database. The application isn't meant to be published, and I want the application to be the only thing allowed to interface with the web service I'll create for DB access.
I've been thinking how I can secure the system, and this is the idea I've come up with. I'd appreciate any feedback or other ideas. Surely there is a method built into Android that I am unaware of.
My thought is to give the web service a GUID. Each time a call is made to one of it's public methods, the web service matches its GUID with the GUID given to it by the Android application. If the GUIDs do not match, the web service refuses access. In short, my system has a 128-bit password.
If you trust the individual to administrative your database then everything should be fine. The most important change is that all of this communication must be done over HTTPS. If a hacker sees this traffic your database will get hacked.
I would still use a username/password combo to access the system. I recommend using the existing mysql.users table with the MySQL password() function. This GUID sounds identical to a cookie, and I would seriously consider using an existing session handling system such as php's session_start() instead of rolling your own. Re-inventing the wheal is bad, especially when it comes to security.