During an engagement on a project management app, I focused heavily on how permissions were handled when data changed states. The app organizes tasks inside workspaces.
I created a task in a public workspace, dropped some comments on it, and then migrated that task to a private, restricted workspace.
As expected, the app locked my low-privileged account out. Loading the task directly threw a standard 403 Forbidden. The core Role-Based Access Control (RBAC) seemed solid. But I always look at the secondary features.
The application separated the task's comment history into an asynchronous Event Log. Crucially, this log was tied to the original public workspace, not the task itself.
When the task was migrated, the backend forgot to migrate the event log or update its permission requirements. So, I went back to the original public workspace and queried its event API, filtering specifically for the ID of the restricted task.
The API bypassed the RBAC entirely and handed over the full, unredacted comment history of the restricted task—even though I had zero access to the task itself.
I moved to the event log of the original public workspace (101) and searched for the restricted task ID (789).
GET /api/v2/workspaces/101/event-log?entity_id=789 HTTP/1.1
Host: api.target-platform.com
Cookie: session_id=attacker_low_priv_session
Server Response:
HTTP/1.1 200 OK
{
"events": [
{
"event_type": "comment_added",
"task_id": "789",
"data": {
"comment_text": "Highly sensitive internal data here..."
}
}
]
}
Organizations rely on private workspaces to isolate sensitive financials or HR records. This flaw silently leaked that protected data in the background. A compromised low-privilege account could use this to quietly monitor confidential discussions without ever triggering an access alert.
The company confirmed the issue and deployed a fix. They acknowledged the impact and paid the bounty reward.