Skip to content

fix: derive user_id from authenticated session to prevent IDOR in AutoGen Studio#7912

Open
AUTHENSOR wants to merge 1 commit into
microsoft:mainfrom
AUTHENSOR:fix/idor-user-id-auth-derived
Open

fix: derive user_id from authenticated session to prevent IDOR in AutoGen Studio#7912
AUTHENSOR wants to merge 1 commit into
microsoft:mainfrom
AUTHENSOR:fix/idor-user-id-auth-derived

Conversation

@AUTHENSOR

Copy link
Copy Markdown

fix: derive user_id from authenticated session, not client-supplied query param

Summary

All API routes in autogen-studio accept user_id as a client-supplied query
parameter
instead of deriving it from the authenticated session. This is an
Insecure Direct Object Reference (IDOR) vulnerability: any authenticated
user can read, modify, or delete any other user's teams, sessions, gallery
entries, settings, and runs by supplying a different user_id value.

The fix uses the existing get_current_user dependency (which extracts the
user ID from request.state.user set by the auth middleware) instead of the
client-supplied query parameter.

The vulnerability

# before — user_id is a QUERY PARAMETER (client-controlled)
@router.get("/{team_id}")
async def get_team(team_id: int, user_id: str, db=Depends(get_db)) -> Dict:
    response = db.get(Team, filters={"id": team_id, "user_id": user_id})

FastAPI treats user_id: str (without Depends(...)) as a query parameter.
A user sends GET /api/teams/42?user_id=victim and receives victim's team
configuration — including agent definitions, model configs, and potentially
API keys embedded in team configs.

Exploitation

# Read any user's teams
curl -H "Cookie: <session>" \
  "https://autogen-studio.example/api/teams/?user_id=victim"

# Read any user's chat sessions (conversation history, PII)
curl -H "Cookie: <session>" \
  "https://autogen-studio.example/api/sessions/?user_id=victim"

# Delete any user's data
curl -X DELETE -H "Cookie: <session>" \
  "https://autogen-studio.example/api/sessions/42?user_id=victim"

The auth middleware IS in place and correctly sets request.state.user. The
get_current_user(request: Request) function exists and correctly extracts
the authenticated user ID from the session. The routes simply don't use it.

The fix

# after — user_id is derived from the authenticated session
from ..deps import get_current_user, get_db

@router.get("/{team_id}")
async def get_team(team_id: int, user_id: str = Depends(get_current_user), db=Depends(get_db)) -> Dict:
    response = db.get(Team, filters={"id": team_id, "user_id": user_id})

get_current_user extracts request.state.user.id (set by AuthMiddleware).
If auth is disabled (type: "none"), it falls back to DEFAULT_USER_ID.

Affected routes

13 endpoints across 5 files:

File Endpoints
sessions.py list, get, update, delete, list_runs
teams.py list, get, delete
gallery.py upsert, list, get, delete
settingsroute.py get
runs.py create

Diff: +21/−20 across 5 files.

Impact

  • Cross-user data access: any authenticated user can read any other user's
    teams, sessions (including conversation history), gallery entries, and settings
  • Cross-user data modification/deletion: any authenticated user can delete
    or modify other users' resources
  • PII exposure: chat sessions contain conversation history which may
    include sensitive user data
  • Config exposure: team configs may contain API keys embedded in agent
    model configurations

Environment

  • microsoft/autogen commit: 027ecf0 (main)
  • Affected package: autogen-studio (Python)

…uery param

All API routes in autogen-studio accepted user_id as a client-supplied query
parameter (or request body field) instead of deriving it from the authenticated
session. This is an Insecure Direct Object Reference (IDOR) vulnerability: any
authenticated user can read, modify, or delete any other users teams, sessions,
gallery entries, settings, and runs by supplying a different user_id value.

The fix uses the existing get_current_user dependency (which extracts the user
ID from request.state.user set by the auth middleware) instead of the
client-supplied query parameter.

Affected routes (5 files, 13 endpoints):
- sessions: list, get, update, delete, list_runs
- teams: list, get, delete
- gallery: upsert, list, get, delete
- settings: get
- runs: create

Signed-off-by: John Kearney <johndanielkearney@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant