9723122, 8:37 AM Insecure Direct Object Reference Prevention - OWASP Cheat Sheet Series
Insecure Direct Object Reference Prevention Cheat
Sheet
Introduction
Insecure Direct Object Reference (called IDOR fromhere) occurs when a application exposes a
reference to an intemal implementation object. Using this way, itreveals the real identifier and
format/pattem used of the element in the storage backend side. The most common example of it
(although is not limited 1o this one) is a record identifier ina storage system (database, filesystem
andsoon).
IDOR is referenced in element A4 of the OWASP Top 10 in the 2013 edition.
Context
IDOR do not bring a direct security issue because, by itself, it reveals only the format/pattern used
{for the object identifier. IDOR bring, depending on the format/pattern in place, a capacity for the
attacker to mount a enumeration attack in order to try to probe access to the associated objects.
Enumeration attack can be described in the way in which the attacker build a collection of valid
identifiers using the discovered format/pattern and test them against the application.
For example:
Imagine an HR application exposing a service accepting employee ID in order to return the
‘employee information and for which the format/pattern of the employee ID is the following
EMP-00800
EMp-e0001
EMP-00802,
Based on this, an attacker can build a collection of valid ID from EMP-00000 to EMP-99999,
Tobe exploited, an IDOR issue must be combined with an Access Control issue because its the
Access Control issue that "allows’ the attacker to access the object for which they have quessed
the identifier through the enumeration attack.
Intps:iicheatshectsories.owasp.ogicheatshectsIneocure_Direct_Object Reference_Prevention_Cheat_ Sheet html 1689723122, 8:37 AM Insecure Direct Object Reference Prevention - OWASP Cheat Sheet Series
Additional remarks
From Jeff Williams:
Direct Object Reference is fundamentally a Access Control problem. We split it out to emphasize
the difference between URL access control and data layer access control. You can't do anything
about the datalayer problems with URL access control. And they're not really input validation
problems either. But we see DOR manipulation all the time. If we list only "Messed-up from the
Floor-up Access Control" then people will probably only put in SiteMinder or JEE declarative access
control on URLs and call it a day. That's what we're trying to avoid
From Eric Sheridan:
‘An object reference map is first populated with a list of authorized values which are temporarily
stored in the session. When the user requests a field (ex: color=654321), the application does a
lookup in this map from the session to determine the appropriate column name. Ifthe value does
not exist in this limited map, the user is not authorized. Reference maps should not be global (Le.
include every possible value), they are temporary maps/dictionaries that are only ever populated
with authorized values,
“A direct object reference occurs when a developer exposes a reference to an internal
implementation object, such as a file, directory, database record, or key, as a URL or form
parameter.”
I'm “down with DOR’ for files, directories, ete, But not so much for ALL databases primary keys.
That's just insane, like you are suggesting, | think that anytime database primary keys are exposed,
an access control rule is required. There is no way to practically DOR all database primary keys in a
real enterprise or postenterprise system
But, suppose a user has a list of accounts, like a bank where database ID 23456 is their checking
account. Id DOR that in a heartbeat. You need to be prudent about this.
Objective
This article propose an idea to prevent the exposure of real identifier in a simple, portable and
stateless way because the proposal need to handle Session and Session-less application
topologies,
Proposition
Intps:iicheatshectsories.owasp.ogicheatshectsIneocure_Direct_Object Reference_Prevention_Cheat_ Sheet html 216,9123/22, 8:37 AM Insecure Direct Object Reference Prevention - OWASP Cheat Sheet Series
The proposal use a hash to replace the direct identifier. This hash is salted with a value defined at
application level in order support topology in which the application is deploye
‘mode (case for production).
multiinstances
Using a hash allow the following properties:
‘+ Donot require to maintain a mapping table (real ID vs front end ID) in user session or
application level cache.
‘+ Makes creation of a collection a enumeration values more difficult to achieve because, even if,
attacker can guess the hash algorithm from the ID size, it cannot reproduce value due to the
salt that is not tied to the hidden value.
This is the implementation of the utility class that generate the identifier to use for exchange with
the front end side:
import javax.xml.bind.DatatypeConverter;
import java.io.UnsupportedEncadingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithnExceptio
pe
* Handle the creation of ID that will be send to front end side
* in order to prevent IDOR
41
public class IDORUti1 {
ne
* SALT used for the generation of the HASH of the real item identifier
* in order to prevent to forge it on front end side.
*
private static final String SALT = "[READ_IT_FRON_APP_CONFIGURATION}® ;
* Compute a identifier that will be send to the front end and be used as
iten
* unique identifier on client side
* eparam realItenBackendIdentifier Identifier of the item on the backend
storage
: (real identifier)
* ereturn A string representing the identifier to use
* ethrows UnsupportedEncodingException If string's byte cannot be obtained
* @throws NoSuchAlgorithmException If the hashing algorithm used is not
g supported is not available
*/
public static String computeFrontEndIdentifier (String
realItenBackendIdentifier )
‘throws NoSuchAlgorithnException, UnsupportedEncodingException {
String frontEndid = null;
Intps:iicheatshectsories.owasp.ogicheatshectsIneocure_Direct_Object Reference_Prevention_Cheat_ Sheet html9123/22, 8:37 AM Insecure Direct Object Reference Prevention - OWASP Cheat Sheet Series
if (realTtemBackendIdentifier != null &&
{realItemBackendIdentifier.trim().isempty()) {
“Prefix the value with the SALT
‘String tmp = SALT + realltenBackendidentifier ;
/1Get and configure message digester
Jie use SHA here for the following reason even if SHAT have now
potential collision:
7/1. We do not store sensitive information, just technical 1D
7/2. We want that the ID stay short but not quessable
7/3. We want that 2 maximum of backend storage support the algorithm
used in order to compute it in selection query/request
“ITF your backend storage supports SHA256 so use it instead of SHAT
NessageDigest digester = MessageDigest .getInstance("shal");
“Compute ‘the hash
byte[] hash = digester .digest(tmp.getBytes("utf-8"));
“Encode is in HEX
frontEndId = DatatypeConverter .printHexBinary(hash) ;
d
return frontEndId;
This is the example of services usingthe front identifier
pe
+ Service to list all available movies
+ @retumn The collection of movies ID and name as JSON response
4
@RequestMapping(value = "/movies", method = GET, produces =
{MediaType. APPLICATION_JISON_VALUE})
public Map listAllNovies() {
MapeString, String> result = new HashMap<>();
try
this.movies. forEach(m -> {
try {
/{Compute the front end ID for the current element
String frontendié =
‘IDORUti1.computeF rontEndIdentifier(m.getBackendIdentifier()) ;
//hdd the computed ID and the associated item name to the result
map
result.put(frontEndrd, m.getName());
} catch (Exception e) {
LOGGER.error("Error during ID generation for real ID {}: ()",
n.getBackendIdentifier(),
e.gettessage());
)
D;
} catch (Exception e) {
//Ensure that in case of error no item is returned
result clear();
Intps:iicheatshectsories.owasp.ogicheatshectsIneocure_Direct_Object Reference_Prevention_Cheat_ Sheet html 46,9123/22, 8:37 AM Insecure Direct Object Reference Prevention - OWASP Cheat Sheet Series
LOGGER.error("Error during processing", e);
+
return result;
}
pe
+ Service to obtain the information on a specific movie
*
+ @param id Movie identifier from a front end point of view
% @retum The movie object as JSON response
+
@RequestMapping(value = "/movies/{id)", method = GET, produces =
{MediaType. APPLICATION_JISON_VALUE})
public Movie obtainKovieName(sPathVariable("id") String id) {
1/Search for the wanted movie information using Front End Identifier
OptionalMovie> movie = this.movies.strean().filter(e => {
boolean mateh;
try
“1Conpute the front end ID for the current elenent
String fronténdId =
‘TDORUti1.computeF rontEndIdentifier(m.getBackendIdentifier()) ;
[Check if the computed ID match the one provided
match = fronténétd.equals(id);
} catch (Exception e) {
/Ensure that in case of error no item is returned
match = false;
LOGGER.error(“Error during processing", e);
}
return matel
})-findFirst(
//We have marked the Backend Identifier class field as excluded
U/from the serialization
1/80 we can send the object to front end through the serializer
return movie.get();
This is the value object used:
public class Movie {
en
* We indicate to serializer that this field must never be serialized
* @see "https://fasterm].github. 10/jackson-
amotations/ javadoc/2.5/com/fastersm1/
* Jackson/annotation/JsonIgnore. html"
*/
eJsonIgnore
private String backendIdentifier ;
Intps:iicheatshectsories.owasp.ogicheatshectsIneocure_Direct_Object Reference_Prevention_Cheat_ Sheet html9723122, 8:37 AM Insecure Direct Object Reference Prevention - OWASP Cheat Sheet Series
Sources of the prototype
GitHub repository.
Intps:iicheatshectsories.owasp.ogicheatshectsIneocure_Direct_Object Reference_Prevention_Cheat_ Sheet html
66