I can call other apps' Activities without problem, including sending them some data and receiving some data back. But I am sending and receiving some sensitive information that could arguably be misused if in the wrong hands. My question is, is this data safe when traveling between appications?
For example, I call an Activity like this:
Intent intent = new Intent("com.my.package.MY_REQUEST_ACTION");
intent.setClassName("com.other.package", "com.other.package.UserActionActivity");
signerIntent.putExtra("INTENT_PASSWORD", "1234");
signerIntent.putExtra("INTENT_COMMAND", "COMMAND_DO_SOMETHING");
signerIntent.setType("text/plain");
startActivityForResult(intent, 0);
And return something in UserActionActivity:
Intent result = new Intent("com.other.package.INTENT_RESULT_DESCRIPTION");
result.putExtra("INTENT_RETURN_RESULT", "...");
result.putExtra("INTENT_RETURN_RESULT2", "...");
setResult(Activity.RESULT_OK, result);
finish();
And so on. But how secure are these extra strings? Do I have to worry about them being accessible to other applications (other than the two involved), either intentionally or through some kind of "hack"? Do I need something like public key encryption?
And is the situation different on rooted systems (i.e. an app with root privileges can, without too much effort, read inter-app communication)?
Do I have to worry about them being accessible to other applications (other than the two involved), either intentionally or through some kind of "hack"?
Let's assume for the moment that neither app has been modified by an attacker.
If so, then in principle, the communications that you have established should be private on non-rooted device. In practice, there have been bugs with activity Intent extras, though none that I know of recently. Of your IPC options, activities are probably the worst choice from a security standpoint, as they have other impacts (e.g., appear in the overview/recent-tasks screen) that increase the likelihood that there is some bug that we have overlooked.
In your code, though, both sides assume that the other app has not been modified. In particular:
Unless you have some security that is not shown, any app on the device can run the code in your first snippet and try to trick the app to return the response in the second snippet.
The code in your first snippet assumes that com.other.package has not been modified by an attacker.
There are ways to help defend against this (e.g., custom signature permissions, checking the signature at runtime).
Also, bear in mind that an attacker can find "1234" without much difficulty.
With regards to the comments advising encryption, given the protocol that you are describing, encryption seems like an unlikely solution. If you have to provide a secret (INTENT_PASSWORD) in the IPC protocol, then there is no shared secret that both apps would have to use for encryption purposes, and I'm not quite certain what public-key infrastructure you would use to offer public-key encryption here.
And is the situation different on rooted systems (i.e. an app with root privileges can, without too much effort, read inter-app communication)?
Absolutely. On a rooted device, all bets are off. That is not tied specifically to IPC, though.
short answer: it is not safe but it needs some effort for the attacker.
long answer:
the transfer can be intercepted by a man in the middle attack:
on unrooted phones:
if you send data to intent.setClassName("com.other.package", "com.other.package.UserActionActivity"); somone can uninstall the original "com.other.package" and install his own "com.other.package" with the same activity that receives the unencrypted data.
For example an attacker can disassemble the original software, add code (that does something with the secret data) and reassemble the code to a new apk (with a different certificate)
On rooted devices: I donot know but i assume it is possible that the "exposed framework" is capable to intercept and redefine android os calls.
Related
I wonder if it is a bad idea to pass critical data between application's activities via intent extras.
For example, assume an application have 2 activities: A and B. Activity B will be started by A and A passes some critical information such as password via an intent extra when starting B.
I wonder if this is a dangerous or bad practice in android. For example, can such an approach leak password to other apps? Is there any better way to do so? Generally, do you know any good reference for learning about bad practices in android coding?
Assuming that you're referring to intents that just start specific Activities, I think you don't need to worry too much.
To take advantage of sensitive information in such intents, attacker will need to do at least one of the following:
Find a bug in Android framework that can be exploited
Upload custom ROM with malicious additions to user's device without user noticing
Upload application APK with malicious additions to user's device without user noticing
While all these scenarios can theoretically happen, I wouldn't bother to safe-guard against them in most cases.
I am developing android an app to detect malicious apps .we are planning to detect malicious apps based on the requested permission.....does permission alone will help us to detect malicious apps or do we need to consider characteristics like use of dynamic code, usage of static http url....any help appreciated. ...
I will breakdonw this question is several smallwer parts:
detect malicious apps
This is perhaps the harderst part in what you desire to do. Most anti virus, anti malware, etc. will usually search a "footprint" in the source code of the binary that is generating the instructions. If you found a number above threshold of footprints, you can guess that file is malware.
we are planning to detect malicious apps based on the requested permission
I am going to say explicitly: no...
As far as I have seem, most "weird" requests, are usually due to the programmers not fully understanding what the permission grants, or even why/what is necessary for.
This is so much an endemic problem, that Google itself changed how permissions work (if I am not mistaken, from K to L, or L to M or something in those updates)
Then again, an alarm app, that wants network access, wants to read all files in the system, wants to read/writte anything anywhere, wants to use your gps, etc etc, then that looks like malware on itself (and usually no READING user would use it).
do we need to consider characteristics like use of dynamic code
Yes. While Java itself cannot interpret its code "on-the-fly", DEX allows us to. And the most common hijacks are usually apps that do nothing, but then create an entry point to render javascript content, and perform some unexpected code.
usage of static http url
That is on itself not that much of a risk, since most browsers will request some security credential, and at least warn the user that he is on un-trusted network. A secondary problem that usually arrives is geerating the URL "on-the-fly" then asking an empty request to alter its request to that.
If an app is then requesting any web-based content bypassing the system (not a security issue, sometimes the programmer is simply making "less effort than necessary to fullfill a client request", then looking at static addresses, or even IPs is usually of no significant security value.
I have an activity which asks for a username and password, then starts another activity in my app to complete a user signup. I want to send the username+password as intent extras to the second activity. Something like:
Intent intent = new Intent(activity, SecondActivity.class);
intent.putExtra("u", username);
intent.putExtra("p", password);
startActivity(intent);
and my manifest defines SecondActivity like:
<activity
android:name="com.me.SecondActivity"
android:label="">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.me.FirstActivity" />
</activity>
and now I'm having doubts about the security of sending the username+password as intent extras like this - is it possible for another app to intercept the invocation of SecondActivity with a spoofed intent filter? Besides that, I wonder what happens with the intent extras, are they ever persisted to disk by the OS? Someone might be able to look at them there if so.
Thanks
The key here is the distinction between Implicit Intents and Explicit Intents. Your example uses an Explicit Intent as your are specifying the exact class your want to run. This is fine, because Explicit Intents cannot be intercepted and will stay within your application.
Implicit Intents however, open up several possible attack vectors. This article talks about it in more detail. I would very much recommend against using Implicit Intents to pass any kind of sensitive information.
From the Android Docs:
Explicit Intents have specified a component (via setComponent(ComponentName) or setClass(Context, Class)), which provides the exact class to be run.
Implicit Intents have not specified a component; instead, they must include enough information for the system to determine which of the available components is best to run for that intent.
As I stated, for your example in the question, passing the password via Intent is relatively secure in that no other application can intercept it at runtime. But it is important to note that this is not always the case, and using implicit Intents could theoretically allow Intent Interception and expose the sensitive information.
Edit:
As for persisting the Intent Extras to the disk, yes this is a risk. Keep in mind however, that if someone has root access on the device and is using it to try to search the disk for this persisted intent information, there may be easier ways for them to get the same information. No matter what you do, someone with root access to the physical device will probably be able to get that password off unless you do some very excellent encryption.
My recommendation on a overall security perspective is to try not to deal with passwords directly in any kind of long term or persistent context. Passwords should only be used during a log in process and discarded immediately afterwards (assuming you are authenticating with a server). Therefore, with the normal use of the application (a legitimate user with a real password), you don't have to worry about a malicious actor inspecting the device memory, because by the time the malicious actor gets a hold of the device, the password has long sense been removed from memory.
It is possible for third-party apps to intercept system-wide intents. I suggest encrypting your data before sending it to the next intent, and then decrypting it once it has been received.
Handling passwords should always be a very short term affair. It's recommended to use them only for authentication request and then discard them. Coming to specifics of your question, i.e., sending password between activities through an explicit intent, this is secure to the extent that no other app will be able to intercept it and view the value. However, the passwords value needs to be maintained somewhere (memory or disk) in order to pass it to your secondary activity. If it's maintained on the disk it's pretty easy to retrieve. If its maintained in memory, an attacker who gets access to your device can root it and then perform memory dump to view the values in the memory. Thus it is not recommended to deal with passwords in this fashion.
I'm making a mobile app where users should be able to start their own radio broadcast channels from their mobile phone. Other users will then be able to browse broadcasts and connect. It also includes some special perks to make it unique.
I've got the general concept of it thought out.
The thing is, I'm not sure how to implement some kind of "server" for it. I could think of two solutions to my problem currently:
Running a server which manages both the list of broadcasts channels,
and also broadcasts the channel to all users.
Running a server which manages the list. It stores a handle for connecting directly to the broadcasters phone.
Now I'm a total beginner when it comes to how demanding something is. Am I thinking correctly if i say that the first solution would overload the server when there are many users on it?
That would make the second option seem good, although if a channel gets popular enough, wouldn't it require insane amounts of bandwidth for the broadcaster?
Help me out guys, as I said I'm a total beginner when it comes to these kinds of things.
I would just use SHOUTcast or Icecast. It is very easy to start up either of these from another application.
These servers are very simple in their operation. Data comes in (usually encoded in MP3 by the source client [your mobile app]), and the server sends the exact data right out the door to any connected clients. It does implement a small buffer so that receiving clients can be initially flooded with data, to speed up the time before audio is played. You could always implement one of these yourself, but there is no sense in re-inventing the wheel.
You absolutely cannot run a server on the phone itself. Not only won't there be enough bandwidth, but each connection consumes some resources, which are extremely limited on a mobile device. You should host the streams on your own servers, and use the mobile device as a source client.
You're going to have to utilize some off the shelf product here. There's no way you're going to write something yourself that will do what you're hoping (unless your product is a total flop, and no one is using it). People can't broadcast much off their phones (your initial thought), so, you'll *have to be re-broadcasting everything for them, to whoever wants to be listening. It doesn't really matter how popular a specific "station" is, because the point is that you have to be broadcasting to whoever wants to be listening. These sorts of solutions require all sorts of very convoluted server mirroring schemes.
I'm not sure if something like SmartFoxServer can help you or if you want to try to leverage a VOIP server of some kind. I'm sure someone else will pipe in with a more specific and useful suggestion, but I can tell you for certain that this is NOT something you're going to write yourself, if you have no experience with this sort of thing.
And not that you asked, but I'll also note that if the users start broadcasting copyrighted material, then you're liable for pirated distribution of it. So, I'd be VERY careful what you allow people to transmit!
I am writing an Android application that interfaces with a RESTful service. This web service essentially fronts a file system, and provides metadata as well CRUD access to the files. My application retrieves the metadata, and exposes it to 3rd party apps through a ContentProvider.
I need to add the ability for 3rd party applications, running on the same device as my app, to CRUD the actual files by making requests to/from my app (not directly with the server). This means they need to either send or receive the contents of the files (which are typically XML or images) through my app.
I have thought of two approaches for implementing this:
Option 1 - Using ContentProvider.openFile
This seems like an obvious choice for giving 3rd party applications the ability to read files from my ContentProvider. I think it starts getting tricky when those applications need to create or update files through my `ContentProvider'. I'll need a callback when they are finished in order to know when to send the new/changed file back to the server. I believe I could use a FileObserver for that purpose though.
Option 2 - Using a Messenger through a Service
With this approach, I can send the files between my application and client applications through the Messenger. The files would have to be passed through a Bundle, so I am not sure what the best format is for transmitting them (File, FileDescriptor, byte array, something else??). I don't have a good handle on whether or not this would cause problems if the files get to be large.
Option 3 - a hybrid approach
Use folder(s) on external storage as a drop box
Communicate CRUD requests, and drop box contents, through a Messenger/Service
Use the ContentProvider to store the status of requests
3rd party app receives status updates through a ContentObserver
Summary
I think using ContentProvider would be the ideal solution, but it seems that the API does not fully support my use case. I am concerned that trying to go down that path might result in a kludgy implementation. If I go with a Messenger and Service approach, I am uncertain of the most robust way to transfer the files through a Bundle.
The hybrid approach seems pretty robust, but the most complex to implement. Files aren't actually being passed around, so performance should be good. However, I fear this is over-architecting the solution.
What is the best approach for transferring files between applications running on the same Android device? Of course, I am open to other options which I have not outlined in my question.
Content provider is definitely the way to go. If you consider that google uses this approach for almost everything then it becomes appaentr that this is the intended design method.
I'm not extolling the virtues of them, but in the land of the blind, the one eyed content provider is king.
Update
There is an example of how to do this in CommonsWare book, see the link provided.
Source of Content Provider/Files
Use the synch framework for content providers. Simply maintain a list of requests and then schedule the sync to download those file. You can also do this on network tickles etc. you can use broadcast intents or contentobserver to notify clients that the file is downloaded.
In essence this is probably similar to your 3rd option but importantly it uses the Android supplied tools rather than rolling your own.
Ad Endum
Best place to start is the android SDK sample in: android-sdk\samples\android-8\SampleSyncAdapter but be warned that there's a load of contacts related stuff that masks the juicy bits. It took me a while to figure out that I could delete almost all of it except the syncadapter
http://developer.android.com/reference/android/os/ParcelFileDescriptor.html can be sent between processes. I believe that there is a subtly where these are explicitly blacklisted from being allowed to be put in intents. They can be sent through AIDL though.
Also, do NOT use the sdcard for this. This is just asking for trouble. One sdcard is world readable, so anyone can see it. Also, you do not always have access to write to the sdcard (it is removed or put in UMS).
Using the SD card is definitely the recommended way to go to share files on Android.
However, I would go with a modified hybrid solution which makes use of startActivityForResult() and onActivityResult() (docs here) on the client side to communicate CRUD requests (and getting the Uri to the file(s) on the SD card if needed) if you don't mind creating a dummy activity as a front end to your service. Clients, once finished with the file(s), can call startActivityForResult() again to alert your app to changes.
Of course this can be done with startService()/bindService() however it doesn't provide an easy way for clients to obtain a status result especially if you need IPC.
Although content providers/resolvers feel like the correct way to go about things, I do feel it is more for single direction requests specific to providing/consuming content.