My Journey into a QA Security Mindset: IDOR vulnerability

Asaf Sahar
AppsFlyer Engineering
5 min readApr 20, 2021

Intro

IDOR was the first web security vulnerability that I learned and tested. Why did I start with this vulnerability? Why did it amaze me after I learned it? Join my journey in the third blog post as part of the series “QA Security mindset,” to get answers to all these questions and more.

If you are a QA engineer and would like to add security tests to your toolbox, I recommend consulting with your Security team to learn what area is most vulnerable in your product and should be prioritized.

I decided to start with IDOR vulnerabilities after consulting with our Security team. I reviewed the latest security bugs and found that automating this vulnerability is easier than others. More information about the automated solution can be found in my previous blog post. If you haven’t read it yet, you can find it here.

IDOR

Insecure Direct Objects Reference (IDOR) is the ability to access Objects (objects such as databases, static files, account data) that you shouldn’t have access to, by providing user input such as transaction id, account email, user id etc.

Example

Let’s say you have 2 accounts on your website that you are testing, let’s call them Account A and Account B.

If IDOR vulnerability exists, account A will be able to get, download or have access to Account B’s information — simple as that. If this vulnerability hadn’t existed, Account A wouldn’t have been able to access Account B’s information.

Let’s see what this example looks like when writing code.

You can see here below, I created a web application that displays user information and a “database” by using a dictionary called users_db:

The URL to this page is: http://0.0.0.0:8000/idor/login

When entering http://0.0.0.0:8000/idor/login the user will receive a basic authentication login pop up, where they will need to enter their email and password and will then be redirected to their account information page.

For example:

Pay attention to the page URL, if the user is a malicious person they can try to change the URL by changing the id from 1 to 2: http://0.0.0.0:8000/idor/users/2 .

Since we don’t have any validation on if the logged in user has permissions to view the requested asset, they will get another account’s information page.

BOOM - We found an IDOR!

Now let’s see how we can prevent it with code, by adding validation on if the logged-in user has permissions to view the requested page.

Now, if a logged in user tries to get a hold of other users’ account information they will get HTTP 401 Unauthorized

Add this vulnerability to your test plan

After understanding how to test my first vulnerability, I was amazed. Turns out it was right in front of me all of these years! Just by manipulating parameters on HTTPs requests, I was able to find IDOR bugs. This made me think about the number of times I looked over HTTPs requests and never thought about how to manipulate them with a security mindset and access data that I shouldn’t see.

I recommend that you add a security section to your test plans, the sooner the better.

It can be done in both ways:

Immediate - When performing functional tests, pay attention to request details: URL, query string parameters, body values and try to look for parameters that you can be manipulated easily. Such parameters can include email addresses, account numbers or any other numeric ids that can be replaced. You can do that by using the Burp tool to see if you can get information from any other accounts.

Long run - After “playing” with several requests try to think about how you can automate these tests. This is exactly how I did it. I tested several HTTP requests, from different services and looked for common parameters. Then I created an Object in Python that holds all the relevant information to create HTTPs requests. Parameters such as path, request method (GET, POST, etc.), request query string parameters, request body, authentication type and more.

Then, if I had one of those common parameters, I marked it with double curly brackets and a name that I decided on, instead of the actual value.

For example:

Request:

GET https://www.mywebsite.com/foldera/file?email=example@email.com&currency=USD

Such object will look like this:

object = TestedEndpoint(request_method = "GET",
request_path = "/folder/file",
request_query_string_params = "email=
{{email_param}}&currency=USD",
request_authentication_type = ’auth1')

The automated solution was implemented as a Python Library. In the package, the parameters are replaced with actual values that I created by including two users that simulate Account A and Account B. I logged in with account A and replaced the values to account B values, sent the request and expected to get a response code different from HTTP 200 OK.

What guided me was the idea of creating a generic solution so that each engineer, from any team responsible for various services, will be able to create tests for IDOR.

The tests check different scenarios:

  1. Login with account A and sending a request with account B values

2. Login with account A and sending a request with empty values

3. Login with account A and sending a request with parameters of account A + account B

And more….

Thanks for reading, I hope you join me for my upcoming posts where I plan on writing about:

PART IV: My Journey into a QA Security Mindset: SSRF vulnerability

PART V: My Journey into a QA Security Mindset: Information disclosure vulnerability

PART V: My Journey into a QA Security Mindset: XSS vulnerability

.

.

.

PART X: To be decided

--

--