Let’s approach this from a different angle.
Say there’s a website. Say there are users on this website. Say each of these users have an ID number, and that a given user (Bob) has the ID of 123. Say when you view the user Bob, the URL looks like this:
That’s a direct object reference. Rephrased, 123 is referencing Bob, who is a user. The user in this case, would be the object. So, a direct object reference.
If you change 123 to 124, the web site might show you a different user. If it does, and it’s not a user you were suppose to be able to see, then this is an insecure direct object reference.
Here’s a real-world example:
The 1133 I have outlined in red is a direct reference to this specific comic. If you change the number, you change the comic you’re looking at.
Proof (I changed 1133 to 113 and got a different comic):
So okay, you think you get it. The object here is the comic, the reference is the number (1133 or 113). So is this one of those “Insecure Direct Object References”?
Is there any reason you shouldn’t be able to see this comic? Or any other comic you could reach using this method that you couldn’t in some other way?
If you pay attention while you’re navigating this web site, you’ll notice that every time you hit the “Next” button, that number goes up by one. The 113 turns to 114. If you push the “Prev” button, 113 turns to 112. Because they go in order, there won’t be any pages you can get to by changing the number in the URL that you couldn’t get to by pushing one of the buttons on the page.
Let’s go back to the first example, where there’s a website with users. Let’s say that instead of viewing Bob’s profile, you click the button to edit your profile. You see that the URL changed to this:
Well, that looks interesting. See that 122? Why does it have a number when you’re editing your profile? The “somesitewithusers.com” is the site. The “edituser” is probably because you clicked on a button that said “Edit Profile”. But why 122?
Remember Bob? His number was 123, which you saw when you were viewing his profile. What if you change the 122 after “/edituser/” to 123, click enter…
Hey look, it’s Bob! And you see a button to change his name, change his username, maybe change his email and password.
And then you can save the changes.
Next time you look at Bob’s profile, it has all the changes you made to it. So hey, that seemed insecure, definitely something the website should not have allowed you to do.
This won’t happen everywhere. Even if you notice a number that’s referencing a user and you change it to another number, the website can check your credentials to see if you should have access to that page, and then deny you access. The website still utilizes direct object references, but those direct object references are not insecure.
So let’s recap. The definition Google gave us was the following:
“…a direct object reference occurs when a developer exposes a reference to an internal implementation object, such as a file, directory or database key. Without an access control check or other protection, attackers can manipulate these references to access unauthorized data.”
The developer is the person who made the website. The “internal implementation object” would be something like a user or a comic. The only reference we talked about was a number in the URL, but the reference can be other things as well, and in other places. It could have been the name of the comic, or some unique piece of information in the user file, maybe their username or email. The reference could have been in a HTTP Request. Accessing unauthorized data would refer to someone doing something like changing Bob’s profile without being logged in as Bob.
What if you can’t make any changes to some page you find, like the comic example above? Is it ever insecure then? If you can’t make changes, then what’s the problem?
Here’s one problem: HIPAA.
If instead of being able to change Bob’s profile you can just learn what his email and home address are, that’s one thing. It’s a bad thing.
But let’s say you’re in a web application with patient information. You can only click on patients within your hospital database; but then you notice when you click on patient records you know were created sequentially, but the numbers in the URL are 124466 and 124470. That doesn’t look right, so you change it to 124467 to see what’s up. Instead, you end up viewing documents on a patient who isn’t in your hospital. That’s a much worse thing.
All because of the way the developer decided to store the data. You couldn’t click on the patient because it wasn’t within your range of access, but even so, nothing is stopping you from incrementing twelve hundred thousand patient records. That’s a violation of HIPAA, and that’s very illegal.
There are many other kinds of direct object references, insecure and otherwise. There are good reasons to utilize direct object references (comics), and there are good reasons to absolutely never use direct object references (patient information). Think about it the next time you see what seems to be arbitrary numbers in a URL.