Fix IDOR and missing authorization in Python and FastAPI
========================================================

Build the signed-in user in a dependency (current_user) from the authenticated
session and the users table, never from request data, and put the same scope
in every query's WHERE clause: same tenant, and the caller's own rows unless
they are a billing admin. Return 404 otherwise, and refuse an export when any
requested ID is out of scope.

Page: https://softwaresecurity.com/fix/missing-authorization/python-fastapi/

What is in this archive
-----------------------
missing-authorization/python-fastapi/   the project: three implementations of the same code and one test suite
  impl/vulnerable.py   (vulnerable)
  impl/fixed.py   (fixed)
  impl/wrong.py   (a plausible fix that still fails)
run-all.mjs   runs the tests in all three modes and checks the results (Node.js only)
LICENSE-CODE.txt

Run it
------
  Tested with CPython 3.14.8. run-all.mjs needs Node.js 22 or later. Supported
  versions: https://softwaresecurity.com/fix/versions/

  From the missing-authorization/python-fastapi folder, install the dependencies
  once (this needs network access):

    python3 -m venv .venv
    .venv/bin/python -m pip install -r requirements.txt

  Then run the tests. IMPL chooses the implementation the tests load:

    # every test passes
    IMPL=fixed .venv/bin/python -m pytest
    # an exploit test fails
    IMPL=vulnerable .venv/bin/python -m pytest
    # a test fails
    IMPL=wrong .venv/bin/python -m pytest

  The JUnit report is written to reports/junit.xml. To run all three modes and
  check the results in one step, run the harness from this top folder (it needs
  only Node.js; --install runs the install step first):

    node run-all.mjs --install missing-authorization/python-fastapi
    node run-all.mjs missing-authorization/python-fastapi

Verified
--------
  11 October 2026 on macOS 27.0 (Darwin 27.0.0, arm64), with python CPython
  3.14.8, fastapi 0.142.2, starlette 1.7.0, sqlalchemy 2.0.54, itsdangerous
  2.2.0, pytest 9.1.1, semgrep 1.180.0, bandit 1.9.4. Versions and results hold
  for that date: run the tests with your own versions before relying on the fix.

Licence
-------
  The code is MIT licensed (LICENSE-CODE.txt). The page text is CC BY 4.0.
