In one android application, I created a database file in data/data/com.rams/databases/dbfilename.
If I created a second application with the same package name (com.rams) and I access the database file created with my first application, the second application is able to access the database contents.
How can I secure the database file created with my first application?
Almost without exception, and regardless of language or platform, there will always be a way for an application running with the relevant credentials, an application running within a certain environment or a user with the relevant credentials to access and read a given file.
You should assume it will always be possible to access a given file in ways you never intended.
Instead of trying to manage access to the file, try to manage comprehension of the file contents. In other words, it won't matter if everything and everyone can access and read a file if the contents are protected such that only an allowed application can understand the contents.
Or, more simply, look into encrypting the file contents if you need to absolutely ensure that nothing other than allowed applications can make sense of what is in a given file.
Related
I have a problem. I am using xyz.db file and which is stored in asset folder. I am copying all data from xyz.db to application db which is stored in data/data/com.xyz/abc.sqlite in storage folder. Now I want to secure asset's xyz.db file. Because It can be easily extract from apk by reverse engineering. Please help me to secure my asset folder's database file.
You can perform the following to make it relatively difficult to access data in DB.
Password protected zip file to contain db which at runtime should be extracted.
Encrypt the file with symmetric key and again at runtime decrypt it.
Utilize sqlcipher that performs encryption for Data at Rest.
In both the above cases you will need to worry about storing the password or key. There is no sure shot way to protect the file but the above would require more effort and should be added as basic protection.
There's no final solution to your problem.
Any technique you'll use can be beaten by a determined skilled attacker.
You have to accept that if you want to store database xyz.sql in your apk file and you later want your app to use it, then it will be also possible for someone that reverse your app to retrieve it. Basically just because the plain text information at a certain moment will be available on the phone.
Hope i've been clean enough
Keep security in mind
As usual in Android the access rights of the database file determine who can use your database. If you follow the standard way presented in the following posts of this series, your database file will be located within the private directory of your app. This means that your app owns the database file and no one else can access it. Even using the other less common ways to create the database you can only grant access to the file. Thus others can access all of your database or nothing. There is no middle ground.
Still: You should never rely on data being safe from prying eyes in the database. Any sensitive data should be encrypted. Very sensitive data should not be stored on the device at all. Keep in mind that if the device gets lost, any misbehaving finder of the device can gain access to the database file as well as to your app. On a rooted device all files can be read. Apps like SQLite Editor make it easy to read even sensitive data – if they are not encrypted:
In cases where data privacy is of utmost importance, you have to revert to secured services or force the user to enter a secret every time before encrypting and storing the data or reading and decrypting them respectively.
source
I am thinking regarding the future options of my app and I am thinking of the idea of backing-up the data from the application's Database and also sharing that data with another phone, say via e-mail, messaging, Bluetooth, you name it, but basically saving it as a file and opening it from the other phone and having the same values on both phones.
What would be the best approach for such an Android application?
Would Content Providers accomplish exactly this or are they concerned with sharing data only between different Apps? Thanks!
I believe it is possible ,
If you read the documentation about the internal storage here, It mentions
You can save files directly on the device's internal storage. By default, files saved to the internal storage are private to your application and other applications cannot access them
So i believe you can copy the whole sqlite DB file to some temp location then share that file via BT or email or any other sharing option .
But DO NOTE, that the same application package can only access the file if you want perhaps another application to use the db then u need to set the SharedUserId , as mentioned here
Content Providers are generally only for sharing your app's data to other apps.
Content providers are the standard interface that connects data in one process with code running in another process.
My app (App A) need to write a textfile which will be stored under another app's(App B) internal memory. Any idea how to implement this?
I have tried the following:
Under both the AndroidManifest.xml file, I have specified the same android:sharedUserId.
From App A, I used:
filePath = getPackageManager().getPackageInfo("packagename of App B", 0).applicationInfo.dataDir;
to get the path and I have confirmed that the path is correct for App B's internal memory.
But I am getting "java.io.IOException: Permission Denied".
Any idea where I have made mistake?
According to official documentation here,
Technically, another app can read your internal files if you set the file mode to be readable. However, the other app would also need to know your app package name and file names.
It's a do-able thing.
So, create a File object with your filepath and call setReadable on it.
Also, check you're not creating the file with MODE_PRIVATE.
I have a lite version of an application that uses a SQLite database. I want to copy that database over to the full version of the application when the user installs the full version.
I have written some code to perform the file copy, but the lite database file always comes up as unreadable. The file is there and I can point to it, but I can't read it to perform the copy.
In the Android documentation, we read:
You can save files directly on the
device's internal storage. By default,
files saved to the internal storage
are private to your application and
other applications cannot access them
(nor can the user).
Note the words, "by default".
Is there a way that I can override that default and make the SQLite file readable by my other application?
Thank you.
I believe you have 2 options.
Set the sql database to be world readable on creation. You can do this by setting the appropriate mode parameter in the call to openFileOutput() or openOrCreateDatabase().
Set the sharedUserId attribute in the manifest of both of your applications so that they have the same user ID. This treats both applications as the same user, giving both applications access to the same private set of files.
The two apps have the same sharedUserId. When I use this code in app1
context.openFileOutput("/data/data/org.me.app2/files/shared-data.dat", MODE_PRIVATE)
I get an exception telling me that the file contains a path separator.
I am trying to write a file from app1 into app2's storage. (I do of course need to make sure that app2's files directory exists first)
Ideally, I would write to a user specific directory instead of an app specific directory, but I do not know if that can be done
First of all, NEVER use a full path to internal storage like /data/data. Let the operating system give you the path (for example, via Context.getFilesDir() or Environment.getExternalStorageState()). Don't make assumption on where the data is.
Secondly - you already are doing that! Unlike File, Context.openFileOutput already prepends /data/data/[package] to your path, so you don't need to specify that. Just specify the file name.
If you really feel that it's safe and necessary, and if both apps share the same user ID using android:sharedUserId in the manifest, you can get a context of the other app by using Context.createPackageContext() and use CONTEXT_RESTRICTED, then use openFileOutput with only the file name.
Open a FileOutputStream of the needed file, relative to this path:
String filePath = getPackageManager().
getPackageInfo("com.your2ndApp.package", 0).
applicationInfo.dataDir;
Since this is months old I assume you've already solved your problem, but I'll contribute anyway.
Sharing data between apps is what ContentProviders are for. Assuming that you know how to write a ContentProvider and access it, you can access files via ParcelFileDescriptor, which includes constants for the mode in which you create the files.
What you need now is to limit access so that not everybody can read the files through the content provider, and you do that via android permissions. In the manifest of one your apps, the one that will host the files and the content provider, write something like this:
<permission android:name="com.example.android.provider.ACCESS" android:protectionLevel="signature"/>
and in both apps add this:
<uses-permission android:name="com.example.android.provider.ACCESS" />
by using protectionLevel="signature", only apps signed by you can access your content provider, and thus your files.
You should not be overwriting other applications files. That said you have two solutions
Use public external storage (like the SD card) to share the file between the apps.
If the other app is not yours then you can't write to its /data directory, without root that is. Anything is possible with root, just don't expect your users to all have root access.
Edit: Developer owns both applications
Thanks for Roman Kurik for pointing this out. A link to his post on SO
From the android docs
android:sharedUserId
The name of a Linux user ID that will
be shared with other applications. By
default, Android assigns each
application its own unique user ID.
However, if this attribute is set to
the same value for two or more
applications, they will all share the
same ID — provided that they are also
signed by the same certificate.
Application with the same user ID can
access each other's data and, if
desired, run in the same process.
So this is exactly the way user id's work in linux, essentially you are the owner of both and have read/write access to both.