I was wondering, when we download an app which is very cool but before you install it ask to give permission for almost everything you have on the phone. Even that app can make call without your permission to your contacts. Given this scenario, how do we say an unrooted device where app data is secured from other app access? if I have an app which stores data on the device memory then would that be accessed by one of those app which takes all permission before installed?
Thanks in advance for your response.
Apps are still sandboxed, they can't access each others internal storage even with requested permissions.
I'm not sure this is the correct forum for your question though as it's not related to developing. This isn't the right site for IT support.
Edit
As mentioned in the comments - anything put somewhere insecure location such as the SD card would be readable, but the default file storage is a bit more secure.
From the android docs (http://developer.android.com/training/basics/data-storage/files.html)
Note: Your app's internal storage directory is specified by your app's
package name in a special location of the Android file system.
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. Other apps cannot browse your internal directories and do not have read or write access unless you explicitly set the files to be readable or writable.
Related
On my Samsung devices I put a file in the /Download folder. When I select the file within my app (via a file browser), the file is called /storage/emulated/0/Download/myfile.db. This name is stored in my app settings.
At the start of the app the file should be opened. First the app checks if the file exists. In some cases, say once every 2 weeks, the file is said to be not existing! This happens also at my friends mobile since half a year.
Why is that happening? For years everything ran smoothly.
This code runs for 6 years. Of course I added the permissions stuff.
Your help is much appreciated!
You can't use the Download as an guaranteed storage place for your files. You should use the Internal storage for the app. This is what Google has written about the download folder:
This space is called external because it's not guaranteed to be accessible—it is a storage space that users can mount to a computer as an external storage device, and it might even be physically removable.
Here you can read more about the Internal storage and the External storage in Android.
Here is some more information about the Download folder from Google.
Caution: The external storage might become unavailable if the user removes the SD card or connects the device to a computer. And the files are still visible to the user and other apps that have the READ_EXTERNAL_STORAGE permission. So if your app's functionality depends on these files or you need to completely restrict access, you should instead write your files to the internal storage.
Can someone explain the permission of the app specific folder /Android/data/< package_name>/files/ as described here http://developer.android.com/guide/topics/data/data-storage.html#filesExternal
It is not clear when it is truly private to the app and when it is world-readable. Is it the case that when the USB mass storage is enabled the files in the external storage, including the app specific folder, are world readable?
I tried using a file manager app (ASTRO file manager) and I am able to see/open files in the app specific folders on the sdcard and this is irrespective of the setting Protect USB storage in the developer options under Settings. I am using Google Nexus 4 running 4.3 version of android.
So it's confusing when this folder /Android/data/appname/files/ is really private to the app.
thanks.
Let's talk some Android security, shall we?
You can not access an application's home directory, on an unrooted device. This would have been a MAJOR security hole.
Creating WORLD_READABLE files is deprecated, and judging by the text in the API, this is one of those cases where "decperacted" means "deprecated".
So - you wanna pass data between applications?
a. You can leave a file in a set place for the 2nd app to fetch. This is a bad idea though. It litters the user's storage space, there is NO SECURITY at all, the 2nd app is not notified about pending updates and you can not easily determine the state of affairs. I suggest you stear away from this approach. Even though, I've included some elaboration in the UPDATE section below.
b. For simple, small chunks of data, I suggest you go the Intent/BroadcastReceiver approach.
c. You can go the ContentProvider approach is you wanna do things the right way.
d. You can go the Intent/Service approach.
e. For true IPC - use AIDL.
UPDATE:
I suggest you begin by reading Google's article throughly. This article clearly deals with the case of transfering large files between apps. Also, as you can clearly witness, the terminology is quite confusing.
So let's review your question in light of Google's article on the subject.
Internal storage is private to your application and can not be accessed by other apps. You can access its directory structure via Context.html#getFilesDir().
Please mind that:
Files written here are deleted when the user uninstalls the app.
External storage can be physically internal (built in storage) or external (removable SD card). There is no security model here, files are visible and accessible to the world. You can access the external directory structure via Context.html#getExternalFilesDir(). Please mind that:
This direcory might become unaccessible (when the user connects the device to a computer or when he removes the SD card).
There might be a seperate directory per device user.
Files remain even when the user uninstalls the app.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Indra's point is correct. for reading EXTERNAL_STORAGE you need to put this uses-permission
try this permission
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
As far as I knew, the files on the external storage are public, but as Indra points out you do need the permission if you want your app to read them:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I think it is only the internal storage files that are private, requiring ROOT access to be read from outside your app (or an app signed with the same key as your app).
My code logic needs an SD card installed in the device. I have added a check for this case in the application's splash screen, but would like to inform users before they download/install this app. Is there a way to achieve this ?
Thanks !
There is no way to do this before the app installs, as the only way to limit such things is by using the <uses-feature> tag. However, that tag has no options for storage requirements. The best warning you can give is to prominently include it in your app description.
On the other hand, every device I've ever heard of an encountered has some form of external storage, be it a SD Card or inbuilt memory mounted as external storage. What you're doing by using the Splash Screen to check for the external storage is the best way to do this, as there is no other option.
There's no way to do that. Your app have to be installed to be able to check user's environment. You could try to to enforce SD card installation of your app, so if there's none Google Play might (not tested) simply not allow app installation at all, but it will not solve your problem as user will still do not know why. Solution is to clearly state in product description that SD card is mandatory. But note, that requiring SD card is risky as many devices does not have any while still offer external storage. My suggestion - just add note about storage requirements and let system deal with it.
I think it is NOT POSSIBLE . You are checking the sdcard on splash screen and prevent user for next process is the right solution or Use android:installLocation for install android application on sdcard.
Beginning with API Level 8, you can allow your application to be
installed on the external storage (for example, the device's SD card).
This is an optional feature you can declare for your application with
the android:installLocation manifest attribute.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:installLocation="preferExternal"
... >
If you declare "preferExternal", you request that your application be
installed on the external storage, but the system does not guarantee
that your application will be installed on the external storage. If
the external storage is full, the system will install it on the
internal storage. The user can also move your application between the
two locations.
When your application is installed on the external storage:
There is no effect on the application performance so long as the
external storage is mounted on the device.
The .apk file is saved on the external storage, but all private user
data, databases, optimized .dex files, and extracted native code are
saved on the internal device memory.
The unique container in which your application is stored is encrypted
with a randomly generated key that can be decrypted only by the
device that originally installed it. Thus, an application installed
on an SD card works for only one device.
The user can move your application to the internal storage through
the system settings.
Look Here for more details .
From my android app, I'm downloading an apk from the web, storing it in application's private storage (openFileOutput(FILENAME, Context.MODE_PRIVATE))
and trying to call the android package installer for this downloaded apk by,
intent.setDataAndType(Uri.fromFile(f), "application/vnd.android.package-archive");
startActivity(intent);
but I'm getting an error which says
Unable to open zip: /data/data/com.test/files/abc.apk : Permission denied
in the LogCat
and,
Parse Error: There is a problem parsing the package
on the phone screen.
Is it happening because the apk file is in application's private storage so the Android package installer can't access it? If yes, is it somehow possible to still get the apk installed (with user's permission of course.) or Am I doing something wrong?
PS: Please don't assume the phone to be rooted.
In addition to Mark Allisons comment, my GUESS is that since you have the file saved to private storage with mode_private, only your application has read/write permission. But you are trying to have the package installer read it which means that the file must be accessed by an External application and therefore should either be MODE_WORLD_READABLE or MODE_WORLD_WRITEABLE.
Or you could save it to external storage where it is world readable by default.
Ok, for now I've figured out a workaround (and which helped me confirming the exact problem also- the problem was that installer couldn't access the apk file). Now, I'm using MODE_WORLD_READABLE instead of MODE_PRIVATE while saving the file in internal storage, and the android installer is able to access the apk and can install it without any error.
Actually, for me the main purpose of using internal storage was that users shouldn't be able to copy the apk file directly (assuming a simple threat model in which a user doesn't have rooted phone, but can browse through the SD card to find the apk and copy it). Though I'm still not sure whether the file is visible to a user now or not? I mean I'm (almost) fine if the downloaded apk can be accessed from an app in the phone, but can't be copied directly by the user.
Would be helpful if someone knowing the exact scope of MODE_WORLD_READABLE could elaborate on the same, specifically whether a file saved in this mode can be browsed in the (unrooted) phone. Also, is it possible to have a better strategy to safeguard the apk while still allowing the installer to access it?
MODE_WORLD_READABLE does say that it can be accessed by whole "world on the phone" so other apps can get it including file explorers. Some programs like es-file manager let you see contents on device private storage even if you are not rooted but don't let you change those files. Why don't you just delete apk file immediately after installation ? Also since you are downloading apk file in your application I am guessing you don't want to use play store but if that is not an issue see Licensing options for your app on: http://developer.android.com/google/play/licensing/overview.html since there is probably use case that covers your requirements.
Is it possible to provide application specific security to the files?. I want the file could only be accessed by the desired application and not by the others.
I assume that you have files stored on the sd-card in mind, since files stored in the internal file system is protected by default.
The only way you can protect your data from other applications is to use some sort of encryption.
Android gives each application its own user id and then the standard Linux file system access rights take care of protecting data stored on the internal file system. There is nothing you need to do to take advantage of this feature, as it is central to the whole security model in Android.
But for external storage, like the sd-card, Android is using the FAT file system to make the cards compatible with Windows. It's a good thought, but since the FAT file system lack any access rights features, everything stored on the sd-card is available to all apps. (An app that needs access to the sd-card will need to ask for permission to do so.)
(This is a huge integrity problem with Android. Sensitive information should not be stored on the sd-card, yet all photos taken are stored there. An app with access to the sd-card and the internet could easily upload all your photos to a server somewhere without you knowing it.)
you can play with the permission by declaring in your AndroidManifest.xml file. As stated in Android developer permission guide:.
For example, an application that wants to control who can start one of its activities could declare a permission for this operation as follows:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.me.app.myapp" >
<permission android:name="com.me.app.myapp.permission.DEADLY_ACTIVITY"
android:label="#string/permlab_deadlyActivity"
android:description="#string/permdesc_deadlyActivity"
android:permissionGroup="android.permission-group.COST_MONEY"
android:protectionLevel="dangerous" />
...
</manifest>
Can you check the webpage and if you are not clear we can discuss here, i have to go over before giving the exact answer.
Edit: Also check this post in so.
Yes. A simple solution is to generate a random cryptographic key using /dev/urandom when the app is installed, store the key in local storage (not on the SD card), and then encrypt the files you store on the SD card using this key. This will prevent other apps from reading the files.
Of course, one consequence of this approach is that the user will not be able to remove the SD card, put it into their PC, and copy those files onto their PC.