GHSA-f35r-v9x5-r8mc
New API: IDOR in VideoProxy allows cross-user video content access via missing ownership check
Packages
| Ecosystem | Package | Affected | Fixed in |
|---|---|---|---|
| Go | github.com/QuantumNous/new-api | < 0.11.4-alpha.2 | 0.11.4-alpha.2 |
Details
As written in the advisory (Markdown source, shown as plain text).
## Summary
The video proxy endpoint `GET /v1/videos/:task_id/content` is vulnerable to an Insecure Direct Object Reference (IDOR). Any authenticated user who knows another user's `task_id` can retrieve that user's generated video content because the handler queries tasks by `task_id` alone and does not verify ownership.
## Affected Component
- Endpoint: `GET /v1/videos/:task_id/content`
- Route middleware: `TokenOrUserAuth()`
- Vulnerable handler: `controller.VideoProxy`
## Details
`VideoProxy` fetches the task with:
```go
task, exists, err := model.GetByOnlyTaskId(taskID)
```
`GetByOnlyTaskId` performs a database lookup using only `task_id`:
```go
err = DB.Where("task_id = ?", taskId).First(&task).Error
```
The authenticated user's ID is available in request context, but `VideoProxy` does not use it. This allows any authenticated user to request `/v1/videos/<foreign_task_id>/content` and access another user's video if they know a valid task ID.
Other task-fetch paths already enforce ownership correctly via:
```go
model.GetByTaskId(userId, taskId)
```
## Impact
An authenticated attacker who knows another user's `task_id` can:
- Download video content belonging to another user
- Bypass tenant isolation for generated media assets
- Cause the server to fetch upstream video content for a task the attacker does not own
For Gemini tasks, the proxy also uses `task.PrivateData.Key` when contacting the upstream provider. In addition, full upstream response headers are forwarded back to the requester.
## Proof of Concept
```bash
curl -o stolen_video.mp4 \
"https://<instance>/v1/videos/<victim_task_id>/content" \
-H "Authorization: Bearer sk-<attacker_token>"
```
Expected result:
- Response returns `200 OK`
- Response body contains the victim's video content
## Recommended Fix
Replace the task lookup in `VideoProxy` with an ownership-checked query:
```go
userId := c.GetInt("id")
task, exists, err := model.GetByTaskId(userId, taskID)
```
References
External links from the advisory. They lead to third-party sites.