 So thanks a lot. Today we'll be talking about seven ways to hang yourself with Google Android. Namely, we'll be discussing the seven most common security mistakes that we think developers can make while writing Android applications. A few words about ourselves. My name is Katrina, and I'm the founding member of Security Research Group at Fortify Software. Now we're part of HP. I primarily work on static analysis tools. So I'm trying to figure out how they can detect security vulnerabilities in the code automatically. And I'm always trying to improve the tools and figure out how to detect more different types of vulnerabilities. So now we're looking at Android. You know, I got interested in security when I was a student at UCSD. I took computer security class and got fascinated with the subject and stayed around and, you know, actually managed to do my master's thesis and security. And so here I am. I have a pleasure of co-presenting this talk with a colleague of mine from UC Berkeley, Erica Chen, and she is going to introduce herself. Hi, I'm Erica Chen. I'm a PhD student in computer science at UC Berkeley. I'm in the security research group. I received my undergrad degree at University of Virginia. My current research interest is in improving mobile phone security. And my most recent work was on vulnerabilities in inter-application communication in Android. Before we proceed, I want to emphasize that this talk is a great example of collaboration between the industry and academia. And we're very, very, very excited to be working with each other because we get to incorporate all the analysis techniques that we both are working on into fortified tools. And these tools are used by, you know, enterprises all over the world. So let's begin. We divided the talk into four sections. First, we're going to briefly introduce Android application. We're basically not sure how many of you are familiar with it and to what extent. So we're going to just give you a brief intro enough so you'll be able to follow the rest of the talk. Then we're going to talk about the seven security vulnerabilities that we think are going to be very, very common in real world Android applications. Then we'll talk about the results of empirical analysis. And we'll conclude with some observations and lessons learned. In terms of introduction to Google Android, we're going to discuss architecture, security model, and also application breakdown. Basically, you know, Android manifest, which is a configuration file that comes with every Android application components of Android application and also inter-component communication. So Android is built on top of Linux kernel. So basically it provides, you know, things like device drivers and memory management. On top of the kernel, we have some native libraries in Z++ and they provide things like graphics and database management and, you know, browser engine WebKit, for example. These can be accessed via Java interfaces. On top of the native libraries there is a modified virtual machine, which is called Dalvik virtual machine, which runs .dex rather than .class files. Let's see, Android applications are written in Java and they're written using the Google Android SDK, which is basically a Java interface that allows you to access the systems and services of the Android platform. So the whole idea behind mobile platform is the fact that you're going to be running lots and lots of different applications on your system. And so you might be, you know, installing and downloading a banking application that's going to be dealing with some sensitive data. And on the other hand, you might be installing a game application right next to it and running on the same system and you actually don't want your game application to be able to access the sensitive data that your banking application is operating on. So in order to achieve this, Android platform makes sure that every application is isolated from each other. So basically whenever you download and install an application, every application is given a unique UID and therefore each application is in a separate process, in a separate VM. And typically applications cannot talk to each other and see each other's, or they can talk to each other, but they can't see each other's private data unless you do something funny. Because the platform is built on top of Linux, Linux file permissions apply, but what's specific to Android platform is this whole system of permissions, so provided by Google. Permissions allow you to protect access to things like sensitive APIs, so APIs that allow you to access, you know, location services, network, Wi-Fi, Bluetooth, et cetera. Permission system also allows you to protect access to content providers, which are basically databases, and it also protects inter- and intra-application communication. Permissions are requested by an application at install time, and so they're also granted once or denied at install time, and then at runtime they're enforced. And now let's talk about the different components of Android applications. So applications are divided into components. There are four types of components. The first type of component is an activity, and activities, they're basically the user interfaces. So each screen you see on your Android application, that's its own activity. Services are components, they run in the background, and they don't interact with the user. So these are well suited for long running processes, so like if you wanted to implement a music player, things that run in the background, that's what a service would be for. Broadcast receivers receive messages from other components. So this can be like for things like system event notifications or messages from third party applications. And finally we have content providers, and content providers are basically, you can think of them as databases. So each application contains a manifest, and the manifest does a couple things. First of all, it declares application components. So as you can see here, we have an example of an Android manifest, and here it's declared there's a my activity and a my receiver. So the components are declared here, and if the developer doesn't declare the components here, then the system would not know about them. The manifest also specifies application requirements. So this can be things like platform versions or input configurations or specific hardware requirements. So in this example you can see here that the developer is requesting the camera feature, it's using the camera feature, and it's also requiring that the minimum SDK version be eight. So most importantly, the manifest is where permissions are requested. So as Katrina said, these are things that are denied or granted at install time. And so here we have, this application is requesting the internet and camera permission. And finally, developers can also create their own permissions. And these will be applied to the global system. So here we have a new permission being created, and the developer can also set how that permission is to be obtained. So they can say that it's a normal permission, and it will be granted automatically on install. They can say that it needs the approval of the user, or it can require that an application requesting this permission has the same signature as the application that defined this permission. So despite the default isolation that Katrina had mentioned, applications can communicate between one another through the use of intents. And you can basically think of intents as messages. They're sent between components of applications. Furthermore, applications can be sent between components within the application, and also components in different applications. So you're using the same mechanism for both inter and intra application communication. And as said before, they can also be used for event notifications from the system. So there are two types of intents, explicit intents and implicit intents. So explicit intents are intents where the sender specifies the recipient by name. So in this example, we have the Yelp application, and I'm sure all of you are familiar with Yelp. You can pick a restaurant and then there's a feature where it will show you where that restaurant is located on a map. And so suppose the Yelp application had a particular map application that they wanted to use. So to do this, Yelp simply creates an explicit intent, addresses it to that particular map application, and then sending the intent will launch that map application. So in this example, with explicit intents, it's important to note that only the specified destination will receive this message. So the other type of intents are implicit intents. And these are intents without a specific destination. So instead the developer specifies this thing called an action in the message, and then it leaves it up to the system to determine which component is most suited to handle that particular action. So actions are meant to describe the general requirements of the intent, and this is so that the sending application, the Yelp application, doesn't need to know what other applications are installed on the phone. So actions should specify what the receiving component should do. So some common actions include the view action, the edit action, but really the action can be any string created by the developer. So going back to the Yelp application, they could have sent an implicit intent with the view action, and then the system will then look at the receiving components and look at what actions can be handled. And in this case, there's only one component that can handle the view action. So the system will deliver this intent to that map application. So in a couple cases, there may be more than one application that can handle this action. So depending on the type of the request, requesting component, either the user will be prompted to choose what the receiving application should be, or the system might decide what that application should be, or the system will deliver it to all possible recipients that can receive that particular action. So in this example, let's say the system will deliver this intent to the browser application instead. So just to give you an example of the code snippets for these intents. In the first example, you see the explicit intent, and you can see that this intent is, the class name is being set. So that's the destination that's being set. And this intent should be used when the developer has a specific intent. And in the second code snippet, you can see the implicit intent. So this, the class name is not being set, instead an action is being set. And this should be used when the developer just needs some component to handle a specific task. So we have all this intent communication. How can components protect themselves? So components can limit their exposure to intents in two ways. First, components can be made accessible to other applications, so explicitly exported, so visible to all applications. Or they can be made private, so only visible to other components within the same application. So the good news is that by default, when you declare components, they're set to being private. However, when a component is registered to receive, that it can receive an action. So it's registered to receive implicit intents. This component is automatically changed to being a public component. And this can be pretty dangerous because it's not something that the developer is explicitly setting, just the status is changing from private to public. And the second way to protect a component is through permissions. So a receiving component can require that a sender has a permission to send to that component. So an example of the second requirement is so on the right side, we have application two. This has two public components. One retrieves a picture and it requires the retrieved permission. The other one takes a picture and it requires the camera permission. And then on the left hand side, we have an application and it has the retrieved permission. So in this example, the displays picture component in application one can send an intent to the retrieved picture component because it has a retrieved permission. It can't send the intent to the takes picture component because it doesn't have the camera permission. So now that I've given you an introduction of Google Android, let's get into the seven ways to hang yourself with Android. So the most common developer mistakes that will make your application vulnerable. So I'll be talking about unauthorized intent receipt, intent spoofing and persistent messages and these are all related to, they're all communication related vulnerabilities. And then I'll also be talking about insecure storage. And then Katrina is going to be talking about insecure network communication, SQL injection and overprivileged applications. So the first attack we have here is unauthorized intent receipt. So in this attack, a malicious application intercepts an intent or steals an intent. So this will occur when the intent that's being sent is implicit, so it's public to the system and it doesn't require that any receiving components have any particularly strong permissions. So what happens in this as a result? Like any, basically if this intent is stolen, any data in that intent will, you know, the attacker will get that data. And it can also change the control flow of the application. So if the intent was to request a specific display, the user interface and activity, then if an attacker provides that display, now the attacker has, you know, control of the screen and if the user gets prompted to put in their password, then the attacker will steal that information. So as a reminder on the bottom, we have a code snippet of the implicit intent. Here it's the set action is being called. And so one of the examples that we found in our analysis is from the IMDB application. So this application has a feature where the user can request to get showtimes listed for movies in the area. And so to do this, the application has a component, showtime search, and it sends information, it sends a request to the results UI, which then will update the user screen. So the user display, the display will either update the screen with the latest showtimes available or it will say that no showtimes are available at all. So this is an example of what the user might see. Here you can see that there is a couple movies listed and it'll have times. So the problem with this scenario is that instead of sending a direct explicit intent between these components, the developer chose to use an implicit intent. So it made both the intent and also the receiver public. So in this, just as a reminder, remember implicit intent means it's going to the system, the system is resolving where that destination should be. So all a malicious application needs to do is register another component, say that it can handle the same actions as the legitimate receiving component. And then when this intent is sent implicitly, the system may deliver the intent to the eavesdropping application. So in the case of the IMDB application, the attacker finds out a couple things. The attacker knows that the IMDB application is being used by the user. They know that the user is looking for showtimes. And then any intent, any data in that intent can also be stolen by the attacker. We've seen this vulnerability in other applications as well. There's another bus application that where the user can get information on where a bus is and when it'll next arrive. And in that application, the attacker can eavesdrop on the bus and determine what the user's location is. So as you can imagine, this is a very clear privacy violation. So our recommended fix for this problem is to use explicit intents whenever possible. So set the class name. And if you're using a broadcast and you want it to go to multiple recipients, then you can also consider adding permissions to that request. So require that the recipients have a permission. And in any case, regardless of whether the intent is holding any sensitive data, don't unnecessarily expose the data in that intent. So if you're only communicating within an application, you don't need it to go out to the system. You know what the recipient component's names are. So the second vulnerability we have is intent spoofing. So in this, the attack is that the malicious application is sending an intent into a legitimate application. So if the legitimate application just trusts the data, trusts the intent, and it uses the data in the intent, then that would result in data injection. If receiving that intent will change the state of the application, that can also occur. And so this problem arises when components are public and they don't require the senders to have any strong permissions. So here we have a reminder of the code. This is a receiver being declared in a manifest. And as you can see here, it's declaring that it can receive this action, my intent action. So it's being made a public component. So this attack exploits a vulnerability on the receiving side. So let's go back to the IMDB example. We had the receiving component that updates with show times or says that there's no location error. So if you recall, it was receiving an implicit intent, which made that component public. And so as a result, a malicious application can simply send an intent to that component. So it can either send it explicitly or implicitly. And if an attacker does this, then if the attacker in particular is sending the no location error, then the user will get informed that there are no movie show times available. So instead of what you would see on the left, which is the list of all the show times, the user would basically, it would be a denial of service. So the user would see that there are no movies available. And then going back to another example, in the same bus application as before, an attacker can inject fake bus information into a component. So the user would see, oh, this bus is arriving at X time, potentially a lie. So the user could basically wait for a bus that never arrives. So our recommended fix for this problem is to use the exported flag when declaring components and explicitly make the component public or private. So always, always make it like, even if you don't need to, always make it explicitly stated and, you know, make it private whenever possible. If the situation is that the component is supposed to be a public component, then consider limiting the interface by requiring that the sender has a permission. So in the second example, you can see that even though the exported flag is true, it also has a permission. So it's limiting the types of intents that can be sent to this component. So in any case, make sure that public components aren't performing any sensitive operations. So our third vulnerability type, is persistent messages. And in Android these are called sticky broadcasts. And this is a particular attack. It's a special case of the unauthorized intent receipt, which is the first attack we presented. To give you a little background first, broadcast intents, there, instead of the typical one-to-one communication, it's a one-to-many communication. So one message is being sent to any components that can receive, potentially receive this message. And then a sticky broadcast is a broadcast intent that persists. So it's expected to stay around. And they're accessible after they've been delivered already. And they're re-broadcast to any future new receivers. So there are a couple problems with this new type of intent. So like the typical unauthorized intent receipt problem, any malicious attacker could basically steal data, any data contained in the intent. But this is a special type of intent. So there are two other things that can happen. So first of all, sticky broadcasts can't be restricted to a certain set of recipients. So you can't require that the recipient has a permission. So there's no limitation on that. And also this intent is expected to stay around. And so the problem here is there's this expectation, but anyone with a broadcast sticky permission can steal that intent and remove it permanently. So here's an example that illustrates that. We have, on the left we have a list of sticky broadcasts. And then we have a malicious receiver. And this receiver has a broadcast sticky permission, which is a normal permission. It gets granted by default when you install an application. So the user doesn't see it. And what the attacker can do is basically remove this sticky broadcast. And so as a result, this new receiver, the victim application that appears later, won't get this data in this sticky broadcast. So our recommendations for this vulnerability is that regular broadcasts should be used whenever possible. And these broadcasts should be used with the requirement of having the recipients have a permission. And also regardless, don't put any sensitive data in a sticky broadcast. Anyone can read it. Our fourth vulnerability is on insecure storage. So what can happen when you have insecure storage? So people will save their passwords, location, contact information, all sensitive data. And if storage is insecure then this can be stolen. So we're looking at specifically at the SD card. So the SD card has files and these are all world readable. So anyone can read it. Users can read it. It can be synced to your computer. So your computer will have those files. And then also the files will persist. Even after the application that created that file gets uninstalled, these files will remain on the SD card. So an example that we found in our analysis is in the Kindle application. So the Kindle application saves a bunch of data on the SD card. First of all it saves the ebooks on the SD card. And this can be a problem because third party applications can read the SD card, which means they can get access to the ebooks. So an attacker can have free ebooks. Whether they can read it or not depends on the DRM. So some are not protected. Another issue is that the covers of the books are also saved to the SD card. And so this is a privacy violation. Some people are sensitive about others knowing what books they read. So this information should not be leaked. And finally the folder, after you uninstall the Kindle application, the folder that contains all of this data retains on the SD card. So an example that you can think of is a common situation is, you know, users want to move on to the next cool phone. So they sell their old phone. And even if the old owner or the new owner does a factory reset on the phone, you know, they're clearing the data on the phone, it's not clearing the data on the SD card. So what happens is when the new owner, well, when the new owner has access to the SD card, can just look at it, they can also install the Kindle application. And the Kindle application will automatically look in this folder and load the books in that folder. So again, this is another privacy violation because we don't want other people to have access to our reading material. And now the recommended fixes for this problem include, so you could do a couple things. You could write to the application's database. You could write to the device's internal storage for the application and make sure to make that file available to other applications. And finally, if you have to store your data on the SD card, then make sure you encrypt that data if it's at all sensitive. And of course, don't put the key on the SD card. People can read it. Okay. And now Katrina's going to talk about the remaining three ways. So the security vulnerability number five that we think developers can make in-secure network communication. And basically just like in the case of in-secure storage, what we're worried about is leak insensitive data. Only in the case of in-secure storage, we're leaking the sensitive data onto an SD card. In the case of in-secure network communication, we're looking it over HTTP. And now obviously this is not anything new. This is not vulnerability specific to mobile world or to Android. This vulnerability existed in regular web applications. And you think that we learned some from our mistakes and we know that sensitive data needs to be sent over HTTPS. But no. Turns out that's not the case. And here are some of the examples. So we use Wireshark to sniff packets coming from the phone. And here's an example. Here's a screenshot of what the mobile Twitter application is for HTTP. And as you can see here, it sends the tweet, which is basically the value of the status parameter in the clear. And in addition to that, it sends things like latitude and longitude of the person who's tweeting along also in the clear. Obviously both of these pieces of information are sensitive because one is the tweet and the other is the location. So the fact that anybody can access that is bad. Here's another example. Facebook application for Android. As you can see from the screenshot, it sends things like contact email, first name, last name, also in the clear over HTTP. And the most alarming part is that the regular web application allows you to set preferences as to how you want your data sent over HTTP or over HTTPS. But in the case of the mobile application for Facebook, this option doesn't exist and everything is just automatically sent over HTTP. So that's pretty bad, too. So what's the recommended fix? Obviously don't do it, don't leak sensitive data, such as passwords and location updates. Use HTTPS when you use web views whenever possible and just in general think about your mobile application in the same way you would think about the regular web application because in a lot of cases they're very similar and most of the attacks that apply to regular web applications will probably apply to mobile applications as well. The good old SQL injection I probably don't have to explain what this is but just basically the idea is that untrusted, unvalidated data is used to dynamically construct SQL queries and that could lead to bad things such as, you know, deleting tables and injecting something into the database and all sorts of other things. Again, this is not new. This vulnerability is not specific to mobile world or Android. Unfortunately it still happens even though, again, we've known about it for a long, long time and here are some of the APIs in the Google SDK that are susceptible to the regular SQL injection. So here are some methods from SQLI database class that you should be aware of. The regular web applications when we think about untrusted input, we basically mean input that comes from outside of the application. So things like, you know, something that comes from a user interface or HTTP request. In the case of mobile world, mobile application, it probably doesn't really make sense to think about user interface as untrusted data because it's going to be attacking yourself. But, you know, all other types of untrusted sources still apply. So anything that comes from outside the application such as, you know, if the data comes from a different application, it should be treated as untrusted because that application could be malicious. Or, you know, if you're a user, you're browsing the web, you're clicking on some malicious link and then all of that also needs to be treated as untrusted. A subset of a SQL injection vulnerability that we call query screen injection vulnerability is something that doesn't allow you to modify the database but allows you to view more records than you're supposed to. Which basically, you know, makes it sort of an excess control type vulnerability. And just like in the case of SQL injection it also happens because untrusted data is dynamically concatenated into a part of a SQL query. So basically in terms of Android the difference between the two is the APIs that are exposed to. Some APIs allow you to specify the entire query as a string, some APIs allow you to specify parts of the query. And so that's how to differentiate between the two. Here is a specific example. Here is a call to a query API that basically returns invoice records for a product category for a particular customer with a specific customer ID sorted by the sort column. So if you supply, you know, fax machines is the value of product category and 1, 2, 3, 4, 5, 6, 7, 8 is the value of customer ID and price is the value of sort column here is what your query is going to look like. And basically it returns you invoice records for one customer, first customer's ID is 1, 2, 3, 4, 5, 6, 7, 8. However, if you have some piece of untrusted data come in and that and because of that the product category is set to something like fax machines or product category equals fax-slash-quote customer ID is 1, 2, 3, 4, 5, 6, 7, 8. And sort column is fax-slash-quote order by price. Then your query looks very, very different. And if you stare at it long enough you'll see that we basically were able to get around the check against the customer ID. And what that means is you now are able to see return you see invoice records for all of the customers rather than just one customer with customer ID 1, 2, 3, 4, 5, 6, 7, 8 which was the intent behind the code. So I hope I it's not surprised anybody what the fix behind SQL and query string injection vulnerability is. Parameterize queries. Make sure you use those and don't just simply concatenate untrusted data into a SQL query . Make sure that you make it very, very clear which part of the query is the command and which part of the query is the data and that's what parameterized queries do for you. The last and probably the most interesting and exciting security vulnerability we want to talk about is overprivileged applications. So overprivileged applications are applications that request more permissions that you really need to in order to run successfully and correctly. So why is that bad? Well, first of all, it violates the principle of please privilege. Again, you're probably familiar with it but basically the idea is that you shouldn't have more authority than you really need to perform a task. And so why is it bad if you do? Well, then if your application has a different type of vulnerability then an attacker is able to exploit it, then an attacker has control over your application and therefore has all the permissions that the application requested and was probably granted even though the application didn't actually need all of those permissions. Another reason why it's bad is because basically people are getting used to these permission checks pop up and some users that are not as security savvy are going to just click okay, okay, I accept. And it's very possible they're going to be downloading some malicious application that requests some scary permission because it needs to steal your data. But on the other hand if you know what security is all about then you might be scared away and you don't want to download benign and just requests scary permission that it doesn't need. So what are, why overprivileged applications happen? What causes those? And our colleagues at Berkeley did some analysis and came up with a number of causes. And basically all of these causes stem from the fact that there is very, very little documentation for the developers in terms of which APIs require which permissions. And I'll come back to that discussion in a few slides. But because of that developers are left with either figuring this information out by trial and error or guessing or turning into message boards. And so here are some of the common causes. One of them is the confusing permission names for example in the second. Others is testing artifacts. So there's a number of permissions that are used for testing such as mock type permissions and so you're supposed to remove them after you're done testing and if you do not remove them then you end up with an overprivileged application. There's also confusion between accessing a protected API and also invoking an application that accesses a protected API. And again I'll have an example in a second. Also there's something we call related methods. So suppose you're a developer and you're accessing this service that has both getters and setters and only the setters require the permission. But you're only accessing getters so you actually don't need the permission. And I think that you need the permission and so you're requested and end up with an overprivileged application. And finally message boards and forums actually suggest wrong things. So let's look at some examples. Here's an example that illustrates the confusion between accessing a protected API versus invoking an application that accesses a protected API. So here we have two applications, a camera application which actually takes a picture and accesses a camera which obviously means it does need a camera permission but then there's also an app one and all it does is that it asks the camera application for a picture. It doesn't actually take it, doesn't access the camera so it doesn't need a camera permission. But the developer might think well, my application has something to do with the camera so probably needs a camera permission. So I end up with an overprivileged application. And here's an example that illustrates both the confusion naming and also the wrong suggestions given by forums and message boards. So for example if you're registering for an Android state change intent then it's suggested that you need an access Wi-Fi state permission but in reality you don't. So what's the recommended fix? Well, the fix is pretty clear just don't request more permissions than you really need to. Of course it's easier said than done and we think that the first thing that needs to happen is for Google to improve their documentation but in the meantime you can use automatic tools that identify overprivileged. A few words about empirical results. So now that we talked about the seven security mistakes that we think people can make writing Android applications you're probably wondering are these mistakes actually real? Do they happen in real and this table should convince you that they are indeed real. So we looked at a bunch of different applications, we scanned them with our tools with many different tools because we have several tools that we use and we did some manual investigation and so you can see that for example unauthorized intent receipts happen in 50% of applications that we've looked at intense poofing happens in 40% of applications in the usage of sticky broadcasts 20% 28% of applications write some sort of sensitive data to insecure storage on the SD card 17% have SQL or queries to re-injection and 31% of all the applications we looked at turned out to be overprivileged. Good questions, so the questions what happened to secure and secure network communication, we don't unfortunately have a good set of data for that, so we've talked about the two examples that we've seen and we've thought that it's important to mention them but we don't actually have the data because it's not that easy to find these things with static analysis tools which is what we've been using. So some challenges that we had to overcome, coding conventions are in the form of callbacks and the Java reflection are pretty difficult to handle by traditional static analysis tools and another big challenge is the documentation and I was personally shocked to see how little of it is documented and somehow we're expecting developers to write secure Android applications and in fact, my colleagues at Berkeley, while they were doing analysis overprivileged applications, they did analysis of the documentation and they realized that Android 2.2 documents permissions for only 78 out of 1207 APIs that the team found and in fact six out of these 78 APIs were documented incorrectly, so for example one permission that was mentioned didn't even exist. In terms of which tools identify which vulnerabilities, Fortify's tool currently can identify five out of the seven represented vulnerabilities and Berkeley tools identify four and after we collaborate and combine the two analysis we plan to be able to identify six out of the seven automatically with the tools. Our work and research and this talk were inspired by a number of other researchers and some of their names of some of them are on the slide so if you want to learn more go read those people's work. And just in conclusion we'd like to say that well it's clear that Android has a set of security pitfalls itself and we think that static analysis tools can help developers avoid a lot of these problems and again we're very, very excited Fortify software and Berkeley to be working together and incorporating state of the art analysis into Fortify's tools that are going to be used and are used by a lot of enterprises all over the world and this is the end of our talk thanks very much and we're open to questions or you can comment.