| Tiago Coimbra

6. Insecure Direct Object References (IDOR)

A digital illustration of a green, alien-like sorcerer figure holding a glowing crystal ball. The character is adorned with intricate, armour-like details, with skulls and geometric patterns in the background, giving it a mystical and futuristic appearance, all set against a black background.

Insecure Direct Object References (IDOR)

Category: #Access-Control-Attack

Attack:
Insecure Direct Object References (IDOR) occur when an application allows users to access objects (such as database records) without proper authorization checks, leading to unauthorized access.

Attack Code Example (URL Manipulation):

GET /account/view?user_id=1234  # Attacker modifies the user_id to access another user's account

If there is no proper authorization check, the attacker can access account details of user ID 1234, even if they are not authorized to do so.

Vulnerable Code (Python Flask):

@app.route('/account/view', methods=['GET'])
def view_account():
    user_id = request.args.get('user_id')
    account = get_account_by_id(user_id)  # No authorization check, vulnerable to IDOR
    return render_template('account.html', account=account)

Remediation Steps:

  • Implement Authorization Checks: Ensure that access to any sensitive resource or object is restricted based on the authenticated user’s permissions.
  • Use Indirect References: Use non-guessable, indirect references (such as tokens) rather than exposing direct object identifiers (like user IDs) in URLs.
  • Logging and Monitoring: Log and monitor suspicious activities, such as repeated access to different objects in a short period.

Safe Code (Authorization check in Python Flask):

@app.route('/account/view', methods=['GET'])
def view_account():
    user_id = request.args.get('user_id')
    current_user = get_current_user()  # Get the currently authenticated user
    account = get_account_by_id(user_id)
    if account.user_id != current_user.id:
        abort(403)  # Access denied, only the owner can view their account
    return render_template('account.html', account=account)

Reference:
OWASP Access Control Cheat Sheet