Bug Bounty Write-ups

Hacking API endpoints and IDOR

What are insecure direct object references (IDOR)?

Insecure direct object references (IDOR) are a type of access control vulnerability that arises when an application uses user-supplied input to access objects directly. The term IDOR was popularized by its appearance in the OWASP 2007 Top Ten. However, it is just one example of many access control implementation mistakes that can lead to access controls being circumvented. IDOR vulnerabilities are most commonly associated with horizontal privilege escalation, but they can also arise in relation to vertical privilege escalation.

Let’s get to the exploits now. Consider the applications as a subscription and billing platform. The application has a feature to add different user roles to manage the created organization by sending invites to their email.

A confirmation email with a signup link is sent to the new user when an admin requests to add a new user.  The list of invited users is displayed as “pending invites” to an endpoint until the users accept invitations.

Well, the admin also has a feature to cancel those invites that were sent to the expected new users. I was trying to check the invite link to see if it’s still valid even after the invitation has been canceled. I fired up my burp and intercepted the request for cancellation.

The application is generating a request on the DELETE method to the server with an API endpoint. Whatever the case, I looked closer at the endpoint: “/snappy/api/pending_invites/sats3yhb4xt6”, The endpoint contains an id. I marked this one as an invitation ID.

I decided to try an IDOR here. I invited another user from a different account. I collected the invite ID from that other account and pasted it here. And it worked! A successful IDOR The response showed the user’s email.

But a new question arrived, how can I collect other users’ invite IDs without accessing their admin accounts? Without better exploits, I can’t report this. I looked again at the invite ID and tried to identify if there was any encryption algorithm. But no result! I went to the repeater and resent the previous request that I had sent a few minutes before.

 

And this time I got a different response! “Couldn’t find UserInvite with ‘id’=3724993831954625322”. That means the numeric id 3724993831954625322 is connected to the invite ID (sats3yhb4xt6), or one of these is encrypted, which was unpredictable for me! So I decided to go deep. I replaced a random character with the string id at the endpoint (/snappy/api/pending_invites/b). And the response I received was quite interesting!

The parameter ‘id’ and its value = 10! I’ve changed the string value to “b,” and this time I found a different value at the “id” parameter!

That means maybe the string id is generated by a numeric id.

Whatever the case, if the application is showing me a dedicated numeric id with a message “Couldn’t find UserInvite with ‘id’=numeric_id”, that means the application is accepting my request and trying to remove a pending invite but couldn’t find the id! Because maybe that invite was canceled or accepted already and the string ID has expired, but the numeric id is still connected to the string id. What if I give any random string or character that might be valid?

In intruder, I decided to fuzz the endpoint with a random string value. And I got a lot of pending invites canceled!

Conclusion: The API endpoint was validating the request only. It was just removing pending invites whenever a request came to the server with that string id. It was just verifying the invite ID and, if it was valid, removing the invite. The application was not validating the request, regardless of where it was coming from or which user made it.

Leave a Reply

Your email address will not be published. Required fields are marked *