Now that we understand how the code is supposed to work let’s take a look at what’s actually happening.
Let’s log in and validate that the protected endpoints are protected.
Let’s leverage the user1 account.
Instructions
Log in with the username,user1
, and the password, password1
.
Once logged in, you’ll be informed that you’ve been granted access to the user account. Next, the page should redirect you to a new page with the following message: “Welcome user1! Your secret phrase is My S3cret Phrase”.
The end result of logging in should be the following URL:
https://localhost/account_secret_phrase?id=1&session=7c6a180b36896a0a8c02787eeafb0e4c
Let’s see what happens if we change the URL’s id
value from 1 to 2.
What is returned?
Access Denied
. This means that the application is correctly leveraging the validate_request
function in the Python code.
Hm, since we’re authenticated as “user1”, let us change our current endpoint in the URL, account_secret_phrase
, to the endpoint /account_password?id=1
. The new URL should be the following:
https://localhost/account_password?id=1&session=7c6a180b36896a0a8c02787eeafb0e4c
When we do this, we should see the following string: “Welcome user1! Your password hash is 7c6a180b36896a0a8c02787eeafb0e4c”
Let’s try the same thing before and change the URL’sid
to 2.
Uh oh! We didn’t receive the “Access Denied” message this time. Rather, we can see the other user’s password hash!
This is an example of an Insecure Direct Object Reference, known as IDOR for short. IDOR vulnerabilities are an incredibly common example of broken access controls. Due to a lack of proper validation, this class of vulnerability allows attackers to access potentially sensitive data directly. Depending on the application, this type of vulnerability can take many forms. An attacker can access sensitive data via a basic number, as we have here, a file name, a GUID value, or some other unique identifier. While some identifiers, such as a GUID, are random enough to be difficult to guess and, therefore, access, some, like basic numbers and filenames, may be easily guessable and accessible.
Now that we understand where the vulnerability exists, let’s fix our code in the next exercise.