# Object-Level Authorisation (IDOR) — OWASP Top 10

Source: https://www.skillbyai.com/en/owasp-top-10/a-idor

> Check ownership on every access.

## Never trust the ID in the request

An **insecure direct object reference (IDOR)** happens when an application uses an identifier from the request (an order ID, a file name) without checking that the current user may access that object. Changing `/api/orders/1001` to `/api/orders/1002` then returns someone else's data. Fix it by scoping every query to the authenticated user or checking permissions on the loaded object, **deny by default**, and write tests that try to access other users' resources. Unguessable IDs reduce discovery but do not replace authorisation.

## Who may do what, to which data

Access control enforces permissions on every request; server-side request forgery abuses the server's own network access.

![Three ideas: object-level checks, function-level checks and CORS, SSRF.](assets/figures/owasp-top-10/section-2-map.svg) — Figure 2.1 — Object checks, function checks and SSRF.

## Vulnerable and fixed endpoint

Python (Flask-style sketch).

```python
# VULNERABLE: any logged-in user can read any order
@app.get("/api/orders/<int:order_id>")
@login_required
def get_order(order_id):
    order = db.get(Order, order_id)
    return order.to_dict()

# FIXED: the query is scoped to the current user; 404 avoids confirming existence
@app.get("/api/orders/<int:order_id>")
@login_required
def get_order(order_id):
    order = db.query(Order).filter_by(id=order_id, owner_id=current_user.id).first()
    if order is None:
        abort(404)
    return order.to_dict()
```

## Centralise authorisation

A shared policy layer or helper (for example "can(user, action, resource)") is easier to review than checks scattered across handlers.

**Quiz:** What is the correct fix for an IDOR vulnerability?

- [ ] Hide the ID in the URL
- [x] Check on the server that the current user may access the requested object
- [ ] Use POST instead of GET
- [ ] Disable caching

*Answer:* Check on the server that the current user may access the requested object. Authorisation on every request.
