Finding more IDORs – Tips and Tricks

Finding more IDORs – Tips and Tricks
February 12, 2021 12 mins

Finding more IDORs – Tips and Tricks

Finding more IDORs – Tips and Tricks

A collection of useful tips, tricks, and techniques for discovering IDORs.

Before working in the Security Testing team at Aon, I set myself the goal of receiving a bug bounty from a public vulnerability disclosure program. As is often recommended, I decided to look for one bug class in as many places as possible. I considered a few options for which bug class to look for, before deciding to go with Insecure Direct Object References (IDORs). Why? Firstly, they can be easy to test for. IDORs do not require a strong development background to understand and could be explained to a beginner in a matter of minutes. Secondly, they are difficult to fully automate testing for. Often, IDORs require a human’s eye to understand where in a request an object is being referenced, which API endpoints are likely to be vulnerable, and where one object could be replaced with another. There are no hard and fast rules for detecting these bugs, so they lend themselves to manual testing and a trained eye. Finally, due to organizations having such bespoke API implementations there is often no blanket fix for IDORs, meaning they are difficult to fully eradicate.

Equipped with this knowledge I began looking for IDORs, expecting to have some luck in a few days or so… After much frustration, three long weeks and having read just about everything on the internet for such a simple bug class, I finally found my first IDOR in the wild. Throughout this process I kept notes on what I was learning about this apparently simple bug class and wrote up a curated list of tips and tricks for finding IDORs. In this post I will share with you the tips that I picked up on my journey to receiving my first bug bounty.

Although this post will assume some understanding of topic, I feel that I should clarify exactly what an IDOR is before continuing. At its core, an IDOR is an access control vulnerability in which an application relies on user-supplied input to reference objects directly. In this case, the object could be a picture, a comment on a post, personally identifiable information (PII) associated with a user or even an entire department within an organization. We have seen the stereotypical use case of an IDOR before: an application is referencing an ID (e.g., id=1101) when retrieving information from the database and an attacker can attempt to change the ID to something else (e.g., id=1104) in the attempt to pull back another user’s information. There are, however, many more attack vectors for IDORs and I hope that the following list of tips will give you some new things to consider when testing.

Technical Tips

Object scope: Is it private or public?

Start by looking at what objects should be publicly readable versus the ones that should not be. For instance, in an online store, product details and reviews associated with each product may be readable by the general public using the following endpoints:

GET /api/products/<product_id>
GET /api/reviews/<product_id>

However, the buyer’s private profile information should not be:

GET /api/users/<user_id>/creditcard/details
GET /api/users/<user_id>/mailingaddress/details

If the API structure looks something like the above, then you can assume that the user-related information should only be visible to that user. That is one of the best places to start testing for high-impact IDORs.

Pro tip: Don’t forget to try create/update/delete operations on objects that are publicly readable but shouldn’t be writable. Can you PUT to /api/products and change a price?

Find patterns in API route naming to discover new endpoints

If you see an endpoint that exposes a resource in typical fashion such as:

GET /api/albums/<album_id>/photos/<photo_id>

Think about what other directories and endpoints there are likely to be in the API. Tools such as Burp Suite Intruder or FFUF are great here when combined with API-specific wordlists. If regular API wordlists are not finding anything, then consider using a tool like CeWL which will generate custom wordlists for individual applications. Sometimes there will be endpoints that the web app itself rarely hits, but you can send your own requests to them if you find one. These can be gold mines! In the above example, you could try looking for:

GET /api/posts/<post_id>/comment/…
GET /api/users/<user_id>/details/…

We can also provide alternative values for each section and test to see if they exist. For example, version 1 of the API may have the appropriate access controls in place, but perhaps version 2 is not fully rolled out yet. You may find that version 2 of the API is still accessible if you make calls directly to it and that it lacks the access controls as it is not finished.

/service/v1/users/<user_id>

Where:

  • service: application context
  • v1: version
  • users: resource
  • <user_id>: parameter
Add IDs to requests that don’t have them

At times, simply providing an API with information that it does not require or expect may produce results. Try adding object identifiers to requests that didn’t originally have them. The application might mistakenly honor the unexpected ID parameter without subjecting it to access control. Something like the following example might get you access to another user’s photo album:

GET /api/MyPictureList → /api/MyPictureList?user_id=<other_user_id>

Some applications will accept client-supplied ID values when creating an object. This ID value can be anything. If you do not see parameters like id, user_id, account_id, pid or picture_id while creating an object, you should try adding one yourself and test it. You may find that you are able to assign arbitrary IDs and then reference the objects.

Pro tip: You can find parameter names to try by deleting or editing other objects and seeing the parameter names used.

Try replacing parameter names

Once you have spent a decent amount of time testing an application, you may start to remember parameters that have been used throughout it. You can try these parameters in other areas and see if they will be accepted. For example, if you see something like:

GET /api/albums?album_id=<album id>

You could replace the album_id parameter with something completely different and potentially get other data.

GET /api/albums?account_id=<account id>

This could be used to obtain a list of a user’s album_ids, which you could then use in the original query. There is a Burp extension called Paramalyzer which will help with this by remembering all the parameters you have passed to a host.

Supply multiple values for the same parameter

Similarly, sometimes an API will require an ID and you can try supplying multiple IDs to provoke odd behavior and potentially bypass access control mechanisms. This is known as HTTP parameter pollution. Something like this might get you access to the admin’s account:

GET /api/account?id=<your account id> →
    /api/account?id=<your account id>&id=<admin's account id>
Try changing the HTTP request method when testing for IDORs

These are some of the most satisfying bugs to find! Sometimes, applications will only enforce access control on the typical HTTP request method that the client will be making but neglect to implement the same access controls across all HTTP request methods.

Try switching POST and PUT and see if you can upload something to another user’s profile. For RESTful services, try changing GET to POST/PUT/DELETE to discover create/update/delete actions.

Try changing the request’s content type

Access controls may be inconsistently implemented across different content types. For example, if your app sends XML to the server with a Content-Type header of application/xml, try rewriting the request to use JSON with a Content-Type header of application/json. Don’t forget to try alternative and less common values like text/xml, text/x-json, and similar.

POST /api/chat/join/123
[…]
Content-type: application/xml → Content-type: application/json


<user>test</user>{“user”: “test”}

 Are credit card details being saved on a website?

When making a second purchase, the client may just be sending a credit card ID number instead of the actual card details themselves. Try looking for and changing this credit card ID number.

Adding someone to a chat?

Alarm bells! Pay close attention to these types of actions as they are often where you can find IDORs. Can add yourself to another chat simply by changing values?

CRUD

Similarly, if there is a copy, move or delete function on the web app then this is a good place to try looking for IDORs! Try testing all CRUD functions (Create, Read, Update, Delete) on every endpoint.

Try changing the requested file type

This one is simple; it is not very common but sometimes requesting a different file type or extension may be enough to bypass the access control. Experiment by appending different file extensions (e.g. .json, .xml, .config) to the end of requests that reference a document.

Does the app ask for non-numeric IDs? Use numeric IDs instead

There may be multiple ways of referencing objects in the database and the application only has access controls on one. Try numeric IDs anywhere non-numeric IDs are accepted:

username=user1 → username=1234
account_id=7541A92F-0101-4D1E-BBB0-EB5032FE1686 → account_id=5678
album_id=MyPictures → album_id=12
Try using an array

If a regular ID replacement isn’t working, try wrapping the ID in an array and see if that does the trick. For example:

{“id”:19} → {“id”:[19]}

Wildcard ID

These can be very exciting bugs to find in the wild and are so simple. Try replacing an ID with a wildcard. You might get lucky!

GET /api/users/<user_id>/ → GET /api/users/*

Error message?

Do not despair. Sometimes applications will throw an error message regardless of if the action you attempted was successful or not. Even if you get an error message, check manually to see if the action worked.

Continuity

Make sure if you are replacing one ID with another that you replace it in every part of the request, not just in one instance. This is an easy mistake to make and could cause you to overlook potential vulnerabilities.

Random or encrypted ID?

These can be tricky and daunting at first. The best option is to try to decode it by looking at a few different IDs. This may reveal that only a small part of the ID is changing in each instance. Knowing this may help you narrow down the link between the decrypted input and the encrypted output.

Try other object IDs if you receive access errors

If you receive an “access denied” response from the server such as a 401 Unauthorized, it’s worth trying other object identifiers to make sure the access controls are uniformly applied. You can use something like Burp Suite Intruder to quickly enumerate identifiers.

High Level Tips

Burp plugins

Find whichever Burp plugin you prefer for repeating requests on the fly and learn it. It will be your greatest companion when looking for IDORs. My personal favorite is Autorize but you can use any plugin that suits you (Authz and AutoRepeater are also popular). These plugins will allow you send requests with the cookies of another user (or as an unauthenticated user) on the fly. They can greatly reduce the amount of time you are spending manually repeating requests and can land you a quick and easy finding on a test.

Start with high-impact functionality

If time is of the essence, try focusing on functions that have a clear security impact such as those involving account/password recovery before moving on to other functions. This also includes any functions that read or write confidential data.

Pay attention to new features

If you stumble upon a newly added feature within the web app, such as the ability to upload a profile picture for an upcoming charity event, and it performs an API call to:

/api/CharityEventFeb2021/user/pp/<ID>

It is possible that the application may not enforce access control for this new feature as strictly as it does for core features.

Conclusion

I hope that this list of tips and tricks gives you some new things to try on your next app test. Once you get the hang of them, finding access control issues can be some of the simplest, most impactful and enjoyable findings you can get on a test, happy hunting!

Author
  • Max Corbridge
    Security Testing, Cyber Solutions

About Cyber Solutions:

Aon’s Cyber Solutions offers holistic cyber risk management, unsurpassed investigative skills, and proprietary technologies to help clients uncover and quantify cyber risks, protect critical assets, and recover from cyber incidents.

General Disclaimer

This material has been prepared for informational purposes only and should not be relied on for any other purpose. You should consult with your own professional advisors or IT specialists before implementing any recommendation, following any of the steps or guidance provided herein. Although we endeavor to provide accurate and timely information and use sources that we consider reliable, there can be no guarantee that such information is accurate as of the date it is received or that it will continue to be accurate in the future.

Terms of Use

The contents herein may not be reproduced, reused, reprinted or redistributed without the expressed written consent of Aon, unless otherwise authorized by Aon. To use information contained herein, please write to our team.

More Like This

View All
Subscribe CTA Banner