Insecure Direct Object Reference
Insecure Direct Object References has been presented on the list of OWASP Top 10 Web application security risks since 2007. This vulnerability allows an authorized user to fetch the information of other users, and could be found in any type of software applications. It becomes an increasingly important issue in application security due to the prevalence of APIs that are gathering users’ personal information, such as health and medical apps.
What is Insecure Direct Object Reference?
Insecure Direct Object References is a type of prevalent vulnerability that allows requests to be made to specific objects through pages or services without the proper verification of requester’s right to the content. It is mostly found in Web applications or Mobile applications.
As OWASP’s description,
“Insecure Direct Object References occur when an application provides direct access to objects based on user-supplied input. As a result of this vulnerability attackers can bypass authorization and access resources in the system directly, for example database records or files”
By exploiting Insecure Direct Object References, attackers can bypass authorization and access resources directly by modifying the value of a parameter used to directly point to an object ( i.e. by modifying the user account ID in a URL string to access the information of other users) . The potentially accessed resources can be database entries belong to other users, files in the system, and more. The references pointing to these resources, which may be exploited by attackers, can be a database key or a directory of a file. If the application takes user supplied input and uses it to retrieve an object without performing sufficient authorization checks, this vulnerability is enabled.
Examples of Insecure Direct Object References
One typical example of attacks making use of this vulnerability is by modifying values of parameters in URL string. Suppose an application uses unverified data in a SQL call that is accessing account information:
@RequestMapping("/getDocument")
... doGet(HTTPRequest request, ....)
{ String query = "SELECT * FROM accts WHERE account = ?"; PreparedStatement pstmt = connection.prepareStatement(query , ... ); //request is an attacker controlled vector which in this case is used in PreparedStatement without verifying if account belongs to the user
pstmt.setString( 1, request.getParameter("acct")); ResultSet results = pstmt.executeQuery();.....
}
The attacker simply modifies the ‘acct’ parameter in their browser to send whatever account number they want. If the application does not perform user verification, the attacker can access any user’s account, instead of only the intended customer’s account.
http://example.com/app/accountInfo?acct=notmyacct
Insecure direct object references vulnerability also allows attackers to manipulate records in database.
Case Study : Yahoo Suggestions
In the case of Yahoo! Suggestions vulnerability, an attacker could modify the parameters in HTTP POST requests to delete 1.5 million records entered by Yahoo users. In the blog of Ibrahim Raafat, an Egyptian Cyber Security Analyst who report this vulnerability, he described how he found it: At first, he found he could delete his comments, so he opened Live HTTP Headers to check the content in the POST request:
prop=addressbook&fid=367443&crumb=Q4.PSLBfBe.&cid=1236547890&cmd= delete_comment
Where parameter ‘fid’ is the topic id and ‘cid’ is the respective comment ID. While testing, he found changing the fid and cid parameter values allow him to delete other comments from the forum, that are actually posted by another user. Next, he used the same method to test post deletion mechanism and found a similar vulnerability in that.
A normal HTTP Header POST request of deleting a post is:
POST cmd=delete_item&crumb=SbWqLz.LDP0
He found that, appending the fid (topic id) variable to the URL allows him to delete the respective post of other users:
POST cmd=delete_item&crumb=SbWqLz.LDP0&fid=xxxxxxxx
Moreover, the attackers may find out the internal naming conventions and infer the method names for operation functionality. For instance, if an application has URLs for retrieving detail information of an object like:
xxx.com/Customers/View/2148102445
xxx.com/Customers/ViewDetails.aspx?ID=2148102445
Attackers will try to use the following URLS to perform modification on the object:
tic.com/Customers/Update/2148102445
tic.com/Customers/Modify.aspx?ID=2148102445
tic.com/Customers/admin
How can ShiftLeft detect an IDOR pattern?
- The first step is to “map out the attack surface in the application where user input is used to reference objects directly”. These locations include where user input is used to access a database row, a file, application pages, etc.
- For all direct references to restricted resources, the application needs to verify the user is authorized to access the exact resource they have requested (verify for default AUTH checks in global handlers or Annotations mapped to each route that mandate AUTH verification)
- If the reference is an indirect reference, the mapping to the direct reference must be limited to values authorized for the current user.
- Identify if a SecureRandom shim exists in a dataflow between exposed sources (HTPP routes) and sensitive sinks (database, filesystem). A shim acts as a proxy to map predictable sequences to random sequences with high entropy.
How can one prevent IDOR with design patterns?
From the cases and examples presented above, we can see that insecure direct object typically caused by several design flaws, such as lack of access control, using direct reference to internal object that is exposed and predictable ( i.e. customer ID are easily guessed because it is integer and auto-incrementing ). Generally, there are several major approaches to prevent and defense insecure direct object references attacks as following.
Access Control
One essential defense is to check access control. On each use of a direct object reference from an untrusted source, the application should perform an access control check to ensure the user is authorized for the requested object or service. One way to implement this is to use role-based authorization. The idea behind is associating a list of roles with a user, and the service code queries the list to make decisions about whether the user has privilege to access the requested object or service at run time.
Indirect Reference Map
An indirect reference map is a substitution of the internal reference with an alternate ID. It is used for mapping from a set of internal direct object references (i.e. database keys, filenames, etc. )to a set of indirect reference that can be safely exposed externally. In the cases of Australian Treasury GST as mentioned above, attackers can make use of the exposure of easily predictable direct references to retrieve records that do not belong to the current logged in user. The direct references are user IDs that are integer and auto-incrementing. Take this as an example, an indirect reference map can be implemented as follows: a) Create a map on the server between that actual key, user ID in the database (i.e. 1011, 1012, …, ), and the substitution, which can be a long hash value or a GUID that is easily generated but difficult to predicted by users.
- The user ID is translated to its substitution key before being exposed to the UI.
- After the substitution key is returned to the server, it is translated back to the original user ID before the record is retrieved.
Validate User Inputs
Always check user input before using it because evil input is the root of cause of this threat. There must be validation performed in server side, since client-side validation cannot guarantee evil input to be avoided. For instance, attackers may make use of proxy tools to capturing and reissuing HTTP requests to bypass the client-side validation.
Use per user or session indirect object references
This approach can be used to prevent attackers from directly targeting unauthorized resources. For example, use a drop down list of resources authorized instead of database key for the current user to limit the user input. The application has to map the per-user indirect reference back to the actual database key on the server