[MUSIC] So let's take a look at this bit of code that we've got here that's trying to make it so that we have a flexible mechanism for storing data on a device. And so in this example, we have a developer who's gone through and built an abstraction called a storage handler that can be plugged into this data storage system. And we can have different types of storage handlers plugged in that are both public and private. So, for example, a public storage handler can store data to the SD card. Whereas a private storage handler can save it to the app's private data storage and encrypt it or do other things to it to make it hard to access. So, it has become a much more complicated problem to look at this code and suddenly decide, is this code secure or not? Is it leaking data under the SD card? One of the areas of difficulty in understanding how this code works is, we have a common interface for storing all data. That is, all data that we're storing is going through the same method. In this case, it's this store data method that takes a key and a value, and stores it. So, when you look at this, take a second and say can you immediately spot the error? And if you did see this code, would you think that it was bad code? Would you think that it was well-structured and modular code and probably whoever built it knew what they were doing? Or would you be suspicious of it because it's not as simple and straight forward as the examples that we've seen before? Let's stop and take a second to look at what this code is actually doing and it'll help us to decide if we like this approach and the series of abstractions that this code is built on top of. The most basic we have a set of key value pairs that are being stored on the underlying storage system. And we take these key value pairs and we pass them to a method called store data. And what store data does is then based on the key, it extracts a type from the data. So we're going to read into the key and we're going to extract the type. And then, based on the type, it's going to look up a handler that can do the actual storage for that particular type of data. And then ask the handler to, and this is our storage handler, not an Android handler, to store the data. And then the handler itself may go and store it in different locations, either the SD card if it's an insecure one, or it may get stored down to the private data of that app. And all of this is dependent upon the key that is put into this stored data method. If that key has a type that says that it's okay to be stored on the SD card then the app will go ahead and store it on the SD card. If the key has an attribute that says that it should be private then the store data method's going to look up the appropriate handler for private data and store in the app's private data, maybe encrypted or applying other things to it. Now, if we look at this from a software engineering, or maybe a software design perspective, this doesn't look all bad. We've got an abstraction that's used to provide modularity inside the stored data method. That is, these handlers allow us to plug in new handler implementations. We've got different handlers that are dedicated to different functions. So it appears like we're building a nice set of abstractions for storing data. Now let's take a look and dive a little bit deeper into one aspect of this application. And that's this extraction of a type from the key. We see that the first thing that we do in order to derive this type is we're extracting a suffix from the type. So we're looking for the N dot something on the keys that are provided. And the idea behind this is that any key that has dot p user on it is going to be assumed to be private data. And any key that has dot group on the end of it is going to be assumed to be public data. And then based on these keys, these suffixes that are being attached to the keys the actual code is going and looking up the appropriate handler and delegating to it by calling the store method. So it's looking up the handler in this map using that type. Now, why is this a problem? Well let's look at this specific code example. If we look down in our save settings method, one of the things that we can see is that we're saving the private groups whatever that is. For this particular app. And we are creating a key that's called private.groups.puser. So this is clearly data that the developer intended to be private. Now, if we look a little further up, what we see is suddenly we have a problem though. Because this expression that's being used to extract the type from the key in this case where we're doing a series of substring operations on the string, the developer didn't think through the fact that there might be keys that had dots within them. And we might end up in a situation where we could extract the incorrect type from the key. So, if we actually apply this function to the private.groups.puser, what we get is groups is what this thing thinks is a suffix. This expression thinks that group is a suffix when in reality .puser is supposed the suffix but sence it thinks it's groups, it extracts groups and uses that as the type. Which then causes the public storage handler to get used when she stores this data on to the SD card. So, in this case it wasn't directly obvious that the developer was doing the wrong thing. But the fact that the user had to write code that uses interface that has a series of abstractions that hid the actual function of the code. It made it difficult to see that private data was actually being leaked onto the SD card. And certainly there are developers that make mistakes and do the obvious things like we've looked at. But probably most of the mistakes that we see out there from a security perspective, or at least I hope they are, are from this type of scenario where we have a complex set of abstractions that cause the developer not to see a mistake in their code that causes a security problem.