GuardAPI

Fix BOLA (Broken Object Level Authorization) in Falcon

BOLA (Broken Object Level Authorization), formerly known as IDOR, remains the top threat in the OWASP API Security Top 10. In Falcon, this occurs when an endpoint exposes an object identifier (like a UUID or integer) in the URI and fails to validate if the authenticated user has the rights to access that specific resource. If you're just querying your DB with a raw ID from the URL, you're leaking data.

The Vulnerable Pattern

import falcon

class UserProfile: def on_get(self, req, resp, user_id): # VULNERABLE: Directly using user_id from URI without ownership check user_data = db.execute(‘SELECT * FROM users WHERE id = %s’, (user_id,)).fetchone() if not user_data: raise falcon.HTTPNotFound() resp.media = user_data

Route: /users/{user_id}

An attacker can iterate user_id to scrape the entire database.

The Secure Implementation

The fix involves two layers: 1. Extracting the 'Principal' (the user's identity) from a trusted source like a verified JWT or session token stored in `req.context`. 2. Scoping the database query so that it must satisfy both the requested Object ID and the User ID. Never trust the ID provided in the URI. If the query returns nothing because the user doesn't own the object, return a 404. This prevents attackers from even knowing if an ID exists, effectively neutralizing enumeration and unauthorized access.

import falcon

class UserProfile: def on_get(self, req, resp, user_id): # SECURE: Identity is pulled from the authenticated context (e.g., JWT middleware) auth_user_id = req.context.user[‘id’]

    # Scope the query to the authenticated user's ID
    # Even if user_id is passed, we ensure it matches the session or use it as a secondary filter
    user_data = db.execute(
        'SELECT * FROM users WHERE id = %s AND owner_id = %s',
        (user_id, auth_user_id)
    ).fetchone()

    if not user_data:
        # Return 404 instead of 403 to prevent resource enumeration
        raise falcon.HTTPNotFound()
        
    resp.media = user_data</code></pre>

About this page

Framework notes in /guides are generated sketches kept for URL stability. They are not human pentest reports and they are not GuardAPI scan output. The product is a GET-only BOLA merge gate. Maintained by GuardAPI. Questions: [email protected]