Secure application data - android

Is is possible to restrict user, from accessing any application data, like SQLite db file, shared pref. file..etc. I have restricted it to certain level. But still, user can access these file, if he boots the device as root user, or super user.
What needs to be done, to restrict the user from accessing my secure application data?

I saw a blog on this somewhere (I'll get the link if I can find it), but basically, there's nothing you can do. The blog author says that whatever data you put on a user's device is now theirs, and if they want at it bad enough, they're going to get it. A root user has access to everything on the device. That's what rooting is supposed to do.
The only way to really protect your data is to pull it from a secured server and not cache it, which is the only way you should be doing it, if you want to keep something from your user.
Found the blog post, suitably titled, "It's the User's Data, Dammit."
http://commonsware.com/blog/2012/05/01/its-the-users-data-dammit.html
You should really subscribe to this guy's blog. He's got some good stuff on there. (No, I'm not plugging. I wish I could be this guy.)

If the phone is rooted there is little you can do to stop access to files stored on the device.
The best you can do is encrypt the data written to the file or the fields in the database using a key that the user has to enter every time they start the app.

Related

Store important data in internal storage

I'm trying understand which is the best way to store sensitive data in Android. In my app i want to insert a classic in-app-purchase model with some coins. My problem is that i'm not sure how to implement this correctly.
The initial idea was to simply use my firebase database, store the number of coins for every user and fetch the data every time the app is launched. This way I can easily detect some inappropriate usage but my users are forced to use the internet to play.
Looking at the documentations, I found this. Can this be a solution? Can I save in the internal storage the number of coins, maybe with some type of encryption, to avoid root user to modify the file? Then when the internet is on I can double-check the local stored variable with the the one in the database.
Thanks
Not an "easy" task.
Technically, you can create a SecretKey and encrypt data, so no normal user will be able to reproduce. If your concern are root users, You are kind of out of luck, as he can hook into your app while it is reading/writing that value.
But to store it online is not a solution in itself. You have to answer questions like: "Do you trust any server input"?
"How to make sure just paid coins are added"?
Have you had a look at Google Play billing?
it provides safe way's to determine if somebody paid or not.
This will require to be online.
If you have a sensitive data to save you can use sqlcipher database .. the good with it that it encrypt the database file itself so even the root user be able to get the database file he will not be able to decrypt it if you use a secured encryption algorithm.
you can find more about sqlcipher here
https://www.zetetic.net/sqlcipher/sqlcipher-for-android/
Since I assume you will grant your app a reading permission of your sensitive data and all writing processes should be reserved server-side, I would not recommend storing the data in a file on a phone, though every encryption can potentially be passed.
Maybe you already have heard about SharedPreferences, which is a good solution for let's say Preferences the user selects and that only shall affect his particular installation of your app. The difference is, that values are not stored in an external file, so not that easy accessible, BUT your app needs to write them, due only the app can access them directly (also your server can't). I am not aware of how your sensitive data is used at all but I would also not use SharedPreferences since it's injective-prone.
Official docs about SharedPreferences.
If security of your data (speaking of Confidentiality, Integrity, Authentication) is your No. 1 priority, simply don't store your sensitive data on the users device. Focus more on creating an API that ensures secure and performant passing of the relevant bits of your sensitive data. Hope this helps to give you a view of which way to go and which to walk around.

Secure a variable in android

I have an integer variable in my application which I want to save for future use. Depending on it's value (like when the value is 0), I will be blocking a functionality of my app and will be requesting an in app purchase for the same.
If I save it anywhere in internal storage, it'll be flushed after Clearing Data, and if I save it in external storage, the path of the file can be easily found by decompiling the code, and server based solutions are out of my scope.
I know that a full proof security is almost impossible, and you might be thinking of downvoting my question, but I really need some advise from experts like you so that I can at least achieve maximum security, so that I can somehow figure out that the variable's value has been tampered and in that case I'll reset it to zero.
I think there is no way to secure the variable without the server implementation, so in order to achieve your functionality you can perform following steps.
First you need to check the In App Purchase product status - If it's purchased by user then you need to unlock the next functionality.
If user has not purchased or subscribe using in app purchase then you need to lock the next functionality.
In case if you want to protect stored data from reading you can use encryption to store something in the file and then use it in your application. Yes, somebody can find a path to your data, but it would be hard to read it. Also it's impossible to modify data, only corrupt.
On the other hand, it's better to use internal storage or preferences. And yes, data actually should be cleared by clearing application data. You should create default value at the start of your application, if requeired field is missing, and store it. Nothing should remains on device if user delete application\clears data.

Storing password for an offline app

I'm developing an app where the user can use it in remote locations. I've created a startup dialog asking for password. I saved the password in SharedPreferences.
My question is, is it a good idea to do that? Or is there a better way for storing passwords for offline apps?
Because when I try to clear the data of my app in settings -> apps, my saved password in SharedPreferencesis also being deleted.
you can hash your password and store it in a file
search for hash function like MD5 or ..
Basically clear data of your app is cleaning what you store in SharedPreferences so that is normal. Store data in with SharedPreferences is usefull but someone with a rooted devices can access to these datas (basically an xml file store in "/data/data/app_packages").
Then you seriously have to consider to encrypt your password before to store it with SharedPreferences.
My question is, is it a good idea to do that?
Generally, it is not a good idea to store passwords in plaintext,
even if it is an offline application and gets cleared sometimes anyway.
Like you mentioned before, all that Information and even the database can be extracted from your Applicatoin Storage when the device is rooted.
Even If the content of that application is trivial, someone can do what mentioned above, just to see what password you use, so he/she can try to hack other accounts of yours..
This is especially the case if more people are using this application.
If you are aware of, and OK with that, you surely can use SP or DB.
If you want to do something in the right direction, you can encrypt passwords,
or hash them (though I recommend not to use MD5, but something like SHA2,Whirlpool,RipeMD2 or even PBKDF2).
Using an encrypted Database like SQLCipher is also nice, since you have to set it up only once, and everything that is added in to your application
afterwards is automatically stored encrypted.
If your only concern is that you dont want to the passwords be deleted, well, if you don't have Server communication, you have to live with that risk :)

Where can I safe store db password on Android Application?

I have an encrypted db with the "sqlcipher library", but now I don't know where I can store the db passwrod in the correct way, inside the app.
I think that SharedPreferences, in PRIVATE_MODE, is a good place to store it; but I'm not sure.
Any suggestion?
Thanks.
Even if you were to hide the password within the app itself, it can still be decompiled and found out. There is no where safe on a device with root. Your best bet would to have the db on a web-server and have the data retrieved from the server. That is the only way to keep a database safe from users (if the server is setup and secure).
I don't know where I can store the db passwrod in the correct way
The "correct way" is for the password to be inside the user's head, as the only reason to use SQLCipher for Android is to allow the user to defend the user's data.
You appear to be attempting to use SQLCipher for Android as a DRM mechanism, which will not work. There is no place for you to store a password "inside the app" that users cannot get to, given sufficient interest in doing so.
Depends on how paranoid you want to be. That will work if the device isn't rooted. If it is rooted, there's nowhere safe on the device.

How can I make sure file gets from phone to server without being tampered with?

I'm wanting to create an android app that gathers information and then uploads to a server -- however I don't want people to be able to edit the file before it's sent to the server. I can do the first part of it, but am unable to do the second part. Can anyone tell me the best way to go about this? I don't mind if the user knows what's in the file, just don't want them editing it and then uploading their edited information to the server.
You're pretty much out of luck since the application is run by the user and the output is controlled by the user. The only way you could take over user's system so he would have no control over it would be using trusted computing with all of the ethical and philosophical implications - see eg. Can You Trust Your Computer? by Richard Stallman. The only thing you can hope for is having a secure connection between your server and user's systems (SSL/TLS) but this is still user's system over which you have no control.
The only correct answer here is Zed's.
The rest of the answers rely on Security through obscurity.
The bottom line is: if device is not totally locked down (= trusted computing) then users can reverse-engineer the application/file-format/network-protocol and submit false data.
Fact of life: people with huge resources (media industry, IT industry) have tried to pull this off (DVD, BluRay, game consoles, etc..) but eventually talented engineers on minimum budget have been able to break this protection schemes.
So, it might work, but only if data is not important and nobody bothers to break it.
There are a couple of approaches you could use here:
Encrypt the file before its saved to the device, the user will be unable to read/modify it.
Encrypt the connection to the server, SSL can protect against a 3rd party interfering with it.
Don't save the file in a public location, place it inside your app's private data directory. The user will be unable to access it.
Depending on how sensitive this information is going to determine which combination of methods to use.
Well as for Android you cannot prevent people from accessing files on the public filesystem.
Maybe there are better ways to handle this but I would simply crypt and decrypt the data before submitting and by using a passphrase or some sort of parity check one could validate the data.
Some rough ideas:
You could view the information that is being sent to the server to the user and then ZIP the file that's being sent with a password beforehand so the user doesn't get a chance to edit it:
Write a password protected Zip file in Java
Of course, you'll have to make sure the user doesn't know the password ...
Or you could build a checksum of the text that's sent and validate the checksum on the server. Here, again, you have to make sure the user doesn't know how the checksum is built and change it accordingly.
Or you could not safe the information to a file at all but into the app's database or private filespace (where non-root-users can't access it).
Whether it's the pasword or the checksum, you could send that information to your server with a normal HTTP-request so it won't be "visible" to the user (followed by a second request that actually sends the file), but if we're talking about users that know how to handle network-sniffers on their phone (needs root, AFAIK), you'll have bad luck, it's their device and their data that's trying to leave it after all :)You could try to use a secure connection to fix this.
What you could do :
Sign the file with your application
Check the signature on the server, check if the certificate is a certificate that is authorized
This will help a bit, but you'll still have the private key bundled with your application... someone may be able to find it and then sign modified files...
Another idea : can you compute the data or is it user generated ? If it's computed why not just compute the data and send it to the server (over SSL) without even writing it to the filesystem ?

Categories

Resources