Hey folks, hope you all are doing well! Recently OWASP Top 10 2021 was released and the Broken Access Control grabbed the first position with the most serious security risk. Broken Access Control issues are present when the restrictions imposed are only on the frontend and the backend APIs are never secured. Using the easily enumerable IDs is the root cause of Insecure Direct Object References (IDORs).
In this blog, I will be mostly focusing on my approach and scenarios which I encountered.
Broken Access Control in simple words means performing the actions outside the set of allowed permissions.
Whenever I test any application which has user roles, I ask myself the following questions:
Let's see some of the scenarios which I encountered.
The application was a password vault. The application allowed the user to store and update the usernames, passwords, ssh keys, and website URLs. When I was testing update account functionality, the application for the password field said: “Leave blank to keep current password”.
Seeing this I questioned myself: How is it binding the password to this account?
After observing the POST request for saving the password I came to know that the application is linking the passwords using a credential_id.
The post request made me curious. So, I meddled with the request by changing it to some other id. I was surprised to see that the account got updated; however, I wondered where I could see the updated passwords. I checked the application and pondered upon a button that tracks password history and showcases passwords to the users. I was shocked to see a password that was never mine! Hence, Insecure Direct Object Reference (IDOR) led me to enumerate the passwords of all accounts in the organization leading to a simple Broken Access Control issue.
In this scenario, the application was some sort of energy tender management platform. In this, the tender was to be approved by higher privileged users. The lower privileged users can only draft the tender and submit it to the Admin for approval. There was one business logic imposed in this application which is when any user is editing the tender details, the other user cannot edit it. For example if the USER1 is editing the questionnaire the USER2 cannot. The tender is locked for this USER2. When the USER2 tried to open the tender for edit while the USER1 is editing, the application will give the following error message:
As per my assumption, the business logic behind the application is that when the Admin is approving the questionnaire, the lower privileged user must not edit it. Because when I tried updating the tender directly by making a PATCH request to the API. The API responded with the following message:
While looking at the response, I discovered that the PUT method is allowed in this case. I changed the method to the PUT method and forwarded the request. To my surprise, the questionnaire got updated. So, by changing the method, I was able to bypass the imposed access control.
This application was for fleet management. This application segregates the companies into groups so that each company can view its shipments. The API request was in the following manner:
https://company.com/api/shipments/XXXXXXXX
Here the id was in capital letters and eight characters long.
Now, if we think of brute-forcing the same, it would have around 268 permutations. I dug a bit deeper to analyze if there is any pattern in the id, and it turned out that the first four characters were the first four letters of the name of the organization and the last four letters were random characters.
So, for example, if the company's name is TESTING Ltd, the id would be TESTxxxx, where x is any alphabet.
Now the permutations are lowered down to 264. So by knowing the name of the company, I was able to brute force the rest of the characters and view their shipments. Analyzing the id made the permutations much lower and practically possible. It made the IDOR almost possible.
Here the application was a project management platform. It allows users to upload databases. The user can also create projects in the application. While working on it, I observed that the dataset uploaded by the user could be associated with the project.
When I uploaded the dataset, the application responded with an integer as the dataset id. The application stores the dataset and assigns a sequential numerical integer as an id. With such IDs, there can be the possibility of IDOR.
So, while creating the project, I observed that the application was passing a dataset. I changed it to the dataset of another user and successfully saved the project. Hence, I was able to attach the database of other users to my project.
In this case, the application was for entity and database management. It had a view-only user and an admin role. There were many vulnerable modules in this application. I was trying to perform all the CRUD operations from the view-only user’s session. The operation which grabbed my attention was DELETE. The application implemented a 2 step delete process:
First, it sent a request to delete the endpoint, which redirected to confirm the delete endpoint, and the response also had some cookies.
Next, using these cookies, the application sent a request to confirm the delete endpoint and the entity deleted. There was no entity id present in the request. So, it was using the cookies assigned in step 1 identify the entity to be deleted.
Using the cookies of the View-only user, I first sent a request to the delete endpoint with the entity id to delete, copied the cookies obtained in the response, and sent a request to confirm the delete endpoint. By understanding the flow of requests in the application, I was able to break the access control imposed.
Once Sir Albert Einstein truly said :
“If I had an hour to solve a problem and my life depended on the solution, I would spend the first 55 minutes determining the proper question to ask for once I know the proper question, I could solve the problem in less than five minutes.”
Questioning properly helps you analyze how the application behaves and come out with various unique test cases. There are misconfigurations at many places. Many times the access control is imposed only on frontend, so checking the APIs or POST request can reveal the issues.