When my application opens a SQLite database, a message is written to the log similar to the following:
dbopen(): path = /data/data/myApp/databases/myDb.s3db
Although I know that people with an unrooted phone will not be able to access that part of the system, I don't particularly like that the path is displayed for anyone to see who might glance at the logs. Plus, people with a rooted phone COULD access the database and it may contain sensitive information.
I know, I know, I should encrypt sensitive data - and I do. The question remains, however, does anyone know how to disable that log message? I haven't yet found a way.
I thank all of you in advance.
I'm not too sure why you're worried about if someone with root, because that won't stop ANYONE with root (disabling the log). It's not hard to just CD into your folder, I have hacked many games in this way.
Just use data structures and save to a file...To my best knowledge you can't disable SQLite logging.
Related
After analyzing my Android application with a security tool, it has detected a high level vulnerability "File unsafe delete check". I have investigated about this, and it seems that the problem is that the application uses "file.delete()".
That function is considered unsafe because data could theoretically be retrieved with a tool that scans all the storage device. So, if that way of deleting is "unsafe"... what is the "safe" way to delete files in Android? (to avoid getting that "security error" that is supposedly a "high level" one). What is the proper way to delete files in Android Development?
I am getting the same security warning in 2 different applications, one made with native Java and the other one with Xamarin Forms. Thank you very much!
what is the "safe" way to delete files in Android?
There is none for the vast majority of Android devices. You use delete() on File.
That function is considered unsafe because data could theoretically be retrieved with a tool that scans all the storage device
If the Android device happens to use a classic hard drive (spinning magnetic media), you can overwrite the data before deleting it. On any sort of flash media, that will be ineffective, as the physical location where the data is written can vary with each write operation ("wear leveling").
So, this really boils down to your objective:
If you feel that the user will be harmed if this data is available to be read, store it encrypted with a user-supplied passphrase.
If you are simply trying to avoid this warning, ask the developers of this "security tool" what they are expecting you to do. Or, find a better tool.
This is not an Android specific issue.
It has to do with how file systems work, and the physical storage media it self.
When you delete a file, regardless of API, what is actually deleted is the record in the files table.
The actual data on disk or flash storage remains.
There is a method for secure deletion:
Before deleting the file, overwrite its contents with garbage or zeros several times.
But, this method only works for magnetic media such as hard disks.
Android devices use NAND flash for storage.
Because the number of writes a NAND chip can take before it fails is a lot less than that of magnetic memory, these chips usually come with a mechanism that spreads out the write commands.
What this means is that even if you try to write random data or zeros over your file, there is no guarantee the actual data will be overwritten.
The writes may go to a different sector to avoid wear.
So, on one hand, for flash storage it is enough to overwrite the file once, but on the other hand, it is impossible to do correctly at application level.
If you want to make your application secure, you must make sure to store sensitive data encrypted.
Then, even if someone tries to read the raw storage, they wouldn't be able to recover the data.
Don't store user credentials (like passwords) in regular files on Android.
Use Android accounts API and let the OS manage security.
If you still need file storage but want to protect the data, encrypt it in memory and then write to file.
As said by the other answers the first thing to consider under a theoretical point of view is if there is really a need to store any sensitive information in files to be kept on customer side
If this is really the case, encryption is the real way to guarantee proper security. Files would be protected not only against the recovery after deletion but also during their known life on the device
That said, in the case of a vulnerability assessment - i.e. a static analysis of the code - it would not be immediate to detect that you are calling for a deletion [via file.delete()] of encrypted files. Or maybe you are just calling the deletion of files with nothing to hide
In both these cases the found vulnerability would just be a false positive. Which is part of the game because you can guess that it's quite complicated for an automated tool to understand if something really "deserves" protection or not
What you can do to get rid of the vulnerability is adding the logic to empty the files before calling file.delete(). You have a sample here for this purpose. This will solve the vulnerability detection you are experiencing
One way I know is to put in assets but thats can't be proguarded and is easily available after decompiling. What are some other ways?
Thanks in advance!
Simple answer is: you can't. You want to make it readable and not readable at the same time. This won't work, never did and never will, unless you're running your software on a locked-down hardware.
You may only make it more or less annoying to extract your precious data from the app. The most obvious way is to encrypt it and decrypt it at runtime. Of course determined attacker will extract the keys and decrypt it without troubles.
You can download it from some backend server at runtime and save on the flash in private data region - of course somebody can just peek inside and copy the files, but APK analysis won't disclose the data.
Finally, somebody can just dump RAM with JSON contents and bypass your "security".
You could encode it with something like AES but even then the data will not be save. It will just be harder to decompile. Additionally, you need to decode it every time you use it.
I'm currently developing an Android game which saves data into a SQLite database. This is not really "sensitive" data, but I don't want users to be able to modify it (for obvious reasons of game balance, as it would be cheating). And it's quite easy to access and modify a SQLite db when your phone is rooted (there are plenty of applications for that in the market).
So should I even worry about that, or consider users with a rooted phone can do whatever they want including cheating and that's their choice? Or could I somehow encrypt the data I don't want them to modify, or add a MD5 checksum or something similar?
Another approach would be to abandon SQLite altogether and use some kind of binary files with game data.
Please let me know if some of you already encountered similar issues, and what are the approaches you followed, as well as the "good practices" in the Android gaming development community.
Thanks.
Root access for everybody and security are mutually exclusive.
Any application or user with root permissions can read and modify each and every file on your system, as well as all of the main memory. That doesn't leave many places to store a potential encryption key for the database.
You could hide parts of the key in the executables, configuration files etc, but everything you could come up with would be nothing more than obfuscation and security by obscurity.
If a user opts to grant root access to everybody, that's their decision, and it's not your job as an app developer to prevent any harm that might be caused.
Update:
Storing API keys in Android, is obfustication enough? is a pretty similar issue - it's about protecting API keys, but it's the same situation with regards to your options.
sqlcipher for Android might help here.
https://guardianproject.info/code/sqlcipher/
I think based on your requirement the best method is using consistency of data,
for example MD5 the score and time, then put score and time and MD5 in to the table, then every time wanting to use that row of DB check the MD5 of the score and time if the one in DB and the one which calculated are same, the row is consistent otherwise it was hacked!
You may find your happiness on Preferences Files Look here
EDIT: Assume a rooted phone for this post.
I deleted a previous question I posted on this topic because none of the answers even came close to answering the question. Long story short, I need to open a database and modify an existing record. I do not want to use a "helper class" because I actually want to see and understand what is going on in a few lines of code rather than an unnecessary (for my purposes) class that contains 100 lines of code. So please don't tell me to "use the notepad tutorial." I have, and it doesn't explain what I need.
To simplify, here is what I am doing:
SQLiteDatabase myDB = this.openOrCreateDatabase("/data/data/MY_APP/databases/settings.db", MODE_PRIVATE, null);
myDB.execSQL("INSERT INTO my_table (SOME_FIELD) VALUES ('SOME_VALUE');");
This works very nicely. However it fails if I try to open/edit a database in a different path. For example I might want to edit a database that another app uses. How can I do this? Is it a simple matter of permissions? Should it work if my app requests and gets root access?
EDIT: There are tons of apps I can install on my phone that are capable of editing every single database on the system so obviously this CAN be done.
Regarding Android security, you cannot access others' app DB directly. If other applications create ContentProvider then you can access theirs DBs (if exist) through its Providers. Otherwise, there's no way out AFAIK.
I don't know if you are still looking for this answer. I was looking to do the same but couldn't really find anything. I knew I needed to use root for the process, but again, couldn't find anything. I started messing around and just trying a lot of random things, and finally found a way to do it.
The short version that worked for me is you need to, as root, change the permissions of the database, access it directly (not through an sqlite helper), do whatever you wish, and then put the permissions back. I detail all of this on my blog:
http://rratmansky.wordpress.com/?p=259&preview=true
In Android applications, what is the best strategy to generate reports that can be viewed later by user? I'm talking about normal running of the application, not necessarily errors & exceptions.
I've a few options in mind but each one seems to have issues:
Logcat (use a specific tag “MyAppsLog”, provide user a functionality to read all statements logged using that tag)
Note: I believe the primary purpose of Logcat is for providing debugging info for the developer, not for the end user.
Manually open a flat file and append your logging statements to it.
Note: Can go this route if there is no standard mechanism for logging and report generation. Since this is such a standard requirement, I'm hoping not to re-invent the wheel. Also, if the application is re-installed the file can get lost. If written in sdcard/external storage to avoid this possibility, might not be private.
Use a third party tool like ACRA
or android-remote-stacktrace
Note: I think the purpose of these tools is crash-reporting, I don't think they are the best bet for standard report generation.
Many enterprise applications need to have a way to generate reports (normal running of app, not error), that the enterprise-user can view later. I'm hoping the answers here would be useful to more people than just me.
Well how about using an SQLite database, and dumping the log data in a table? Beats the flat file option I think. You can even aggregate dumped data or start queries on it.
Sqlite is heavy and taking lots of memory and process.
Advantages of flat file:
single point of all log info,
easy to manage,
easy to delete (clear cache)
performance (when file size grow up) performance of apps remain same
Anyone can read log file and can know which process is running on
if data is not big/complex, not that much important (if any one read it) then use flat file only.