Skip to content

[CRITICAL] DELETE /users/{id}/gdpr has no authentication or ownership check #107

Description

@jsogarro

[CRITICAL] Unauthenticated GDPR data-deletion endpoint

Summary
DELETE /api/v1/users/{user_id}/gdpr deletes a user's database rows (research projects, agent tasks) and purges their memory-system data, but the route declares no authentication or ownership dependency at all — any unauthenticated caller can delete any user's data by guessing/enumerating a UUID.

Evidence
src/api/routes/users.py:30-34

@router.delete("/{user_id}/gdpr")
async def delete_user_gdpr(
    user_id: UUID,
    db: AsyncSession = Depends(get_session),
    memory_system: MultiTierMemorySystem | None = Depends(get_memory_system),
) -> dict[str, Any]:

The global AuthMiddleware only initializes request.state and performs no token validation itself (per its own docstring); real authentication only happens where a route separately adds Depends(get_current_user) or similar. This route has neither.

tests/test_pii_privacy.py:181-238 (test_gdpr_delete_purges_user_database_rows_and_memory) calls the endpoint with no Authorization header at all and asserts the deletion succeeds — the only test covering this endpoint demonstrates the vulnerability while treating it as the expected happy path. No test anywhere asserts a 401/403 on this route.

Failure scenario: an unauthenticated request to DELETE /api/v1/users/{any-uuid}/gdpr succeeds and permanently deletes that user's research projects, agent tasks, and memory-tier data.

Impact
Any caller who can reach the API can destroy an arbitrary user's account data with no credentials. This is a full, unauthenticated data-destruction primitive.

Remediation
Add an authentication dependency to the route (e.g. Depends(get_current_user)), and verify the authenticated caller is either the target user or holds an admin/GDPR-operator role before proceeding. Add a regression test asserting 401/403 for an unauthenticated or non-owning caller.

Acceptance

uv run pytest tests/test_pii_privacy.py -v

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions