[MUSIC] Let's take a look at some of the ways that we can write apps that accidentally leak data to other malicious apps on a device by not properly securing our interactions with the storage system. Now as we've seen, as in most cases, we have a process boundary which protects our app and its memory from another app. And also, as we've discussed, we have an area within the storage system that by default, whenever our app saves data, allows us to save it privately and prevent other apps from getting access to it. But there certain types of interactions with the file system that if our app uses those interactions, it will end up storing data in a way that it's accessible to other apps on the device. So there are cases where we can store data and think that we are storing it securely. But in reality, we're opening up the ability for malware to get access to that data and then steal it from our application. So we always want to make sure that whenever we store private data on Android, that we do it properly. And that we don't do it in a way that allows other applications to gain access to it. So let's take a look at one particular way that we can accidentally leak data from our app to other apps in the device. And this is actually quite a common way that developers make mistakes and end up exposing important settings or private user data to other apps. So the way that developers often make a mistake is they assume that data that they're storing to the SD card is secure. Or they assume that other apps aren't going to look at the data or know to look for the data that their app is saving on the SD card. And this is actually not true. If you store data on the SD card, it's actually public to all other apps on a device. So whenever you see code that has getExternalStorageDirectory, you need to be very careful that you ensure that nothing private is being stored to that external storage director. And the reason is the external storage directory is typically the SD card. But it is almost always a public area for storing information that any app can potentially can get access to, regardless of what user account saved the data there. So just because your app saves data there and has a separate user account from another app, it doesn't mean that that data that's stored on the external storage directory is actually secure. So what you want to look for is the creation, for example, in this case, of a file that's being stored, with the parent directory being the external storage directory. So, in this case, the user that's logging in has a username and password, and then developer's actually taking that password and storing it on the external storage directory. And then we see, finally, they write the actual password to the external storage directory. And there's a whole host of issues with storing passwords on disk. But even if this wasn't a password, it was some other secure setting, it's still a problem. And the reason is because we've gone from secure data to the external storage directory and then written that data there, assuming that it was private in some way, when actually it isn't. As I mentioned a second ago, you don't really want to store passwords on disk. If you can come up with a design for your application that doesn't require storing passwords, if you can use a token authentication scheme, where you get tokens from a server or force the user to log in each time in order to gain access to critical settings or private settings. You're probably much better off than if you're storing passwords on disks. It's very difficult to store something sensitive like a password on disk and do it in a very secure manner. You have to know exactly what you're doing and be very, very careful with this. If you absolutely have to store something sensitive like a password on disk, you really need to understand how to encrypt that data properly or how to hash it properly, using something like bcrypt. And you don't want to do this unless you absolutely understand what you're doing. You don't want to develop your own homegrown encryption scheme for storing stuff to disk. And now there have been cases of apps where people have taken things like Google Protocol Buffers, which encode data into a binary format that isn't necessarily human readable. And they've stored data in that format assuming that it was secure on disk. But the reality is, is that even something like Google Protocol Buffers isn't secure. It's not a real security mechanism. If you're going to actually store something on disk, you need to do it with a real strong, well known, well studied encryption algorithm. And you don't need to build your own implementation. You need to use an existing implementation. The actual algorithms and processes for encrypting data and storing it on disk are beyond the scope of this MOOC. But I encourage those who are out there and are going to write applications that store data of this sensitivity on disk, to go and look at the available encryption options for storing data on disk on Android. Regardless of if you're encrypting data or not, anything private should never get stored on the external storage directory. There is no reason to take data that's private, even if it's encrypted, and possibly expose it to other applications by storing it on the SD card. If you see data that's going to the external storage directory, check and say, is this data something that's public? Do I want every other app to read it? And if there's any case where you say, I don't want another app to read it, then you shouldn't be storing it on external storage. You must approach external storage with the mentality that anything you store there will be read by other applications. And they will be able to interpret that data. And they will be able to do things with it. If you take that mentality, then it makes it easier to make a decision about what goes on external storage versus doesn't go on external storage. And to make decisions that don't end up exposing user data or exposing private settings from your application. So what would be an acceptable use of external storage? Well, one common acceptable use of external storage is to store photos. So for example, if you have a custom camera application, you probably want to store those photos to the SD card. So that the user can use their phone like a camera, pop in an SD card, take a bunch of photos, store them to the SD card. And then pull that SD card out and put a new SD card in when the SD card that they'd been using before became full. So in that case, it probably does make sense to store those photos on the external storage directory. Also, if they're stored on the external storage directory, it can allow things like the gallery application to more easily get access to them. So there are cases where we want to store it at external storage. But we have to remember that we can't just assume that because we're taking a photo, or we're taking some other type of data, that it's necessarily appropriate for external storage. So for example, although we might have an application where we're actually storing something that is benign, maybe it's really is a innocuous photo that we're storing on the actual SD card. It's not going to be the case that it always make sense to store photos on the SD card. So if you're building Snapchat, you don't want to store photos on the SD card. Because the whole purpose is the photos are private and can't be seen. So you need to be very careful and evaluate whether or not it makes sense to store data on the external storage or SD card of the device. Another mistake the developers make sometimes is that they will actually go and store data to this private region on their device's data directory. But they'll go and store it in a way, with permissions that allow it to be accessed by other applications. So by default, when you store data to an app's private data directory, it's associated with the user account of your app and set to a permission that prevents other apps from accessing it. But you, as the developer, have the ability to override those permissions. And make it so that even though you save it to your private data directory, you give permissions to that file that allow others apps to go and access it within your private data directory. So in this code example here that we're looking at, we're actually opening a file and saving it to our private data directory. But we're saving it with MODE_WORLD_READABLE. And what this means is that any other app on the device can actually get access to that file, even though it's stored in our data directory. And you may think, well this would never happen, I would never do this. Skype actually had a bug where incorrect permissions were being set on the SQLite database that they were using. And you can go and look at the details of this bug. But it exposed data and important settings from that app to other apps on a device. Now here we see the actual case where they're taking this output stream that's been created, and it's been created world readable. And then writing the secret to the output stream and saving this data to the desk incorrectly. So if we look at the overall chain of events that took place from the developer's code that allowed this vulnerability to occur, is we start with a secret setting, so some data that we don't really want exposed. We then, unfortunately, began saving it by opening it in an output stream to a world readable file. And then we actually write that data to that world readable file. And so any time, like when we see MODE_WORLD_READABLE, we need to really think about do we plan on having this data accessed by any other app on the device? Do we really want that? And if the answer is no, we don't want that data accessed by any other data or any other app on the device, that that data that isn't always something that should be public, then we need to go and rethink how we're saving that data. The way that we really should have been implementing this save settings mechanism, if we wanted to keep those settings private to that app, is we should've used MODE_PRIVATE, which tells Android that that data is private to your application and should not be shared. So in this case, we actually are saving settings to the device in a way that other apps can't get access to. So if we see MODE_PRIVATE, we should assume that that data that we're storing to that location will not be accessed by other apps. But what we do need to remember is that just because data can't be accessed by other apps on the device, doesn't mean that it can't be accessed by other users on the device. Just we're saving data that is not accessible to other apps on the device, doesn't mean that the owner, or whoever has physical access to the device, can't see that data. And this, unfortunately, is a mistake that developers commonly make, as we've discussed. Is they assume that something that is stored by their app that isn't visible to other apps is also not visible to whoever physically has the device. And that's not actually the case. If you are holding a device, there are lots of attacks and ways that you can, for example, root the device and plug it into your computer and look at an app's private data. So you shouldn't take anything that is your private data and store it in your app or on the devices of your users. If you give your app access to your own private developer data, you're then distributing that data to all of your users. And essentially saying, I want all of the users of my app that I wrote to have access to my private developer data. Anything that you put into your app or give it at runtime, the user of that app, or a holder of that device, potentially has access to. So in this case, for example, doing something that's very commonly done, and Amazon actually scans for now on GitHub and other locations. Like storing your Amazon Web Services private key on your app. Or storing it on the disk on the device that your app is installed on. Even if you go and download that key after installation and store it, you’re still exposing that private developer data to all of the users of your app. So you don't need to take data that belongs to you and is private to you and ever gives it to your app or store it on a device that your app is installed on, even privately, and assumed that it's safe.