GHSA-F35R-V9X5-R8MC

Vulnerability from github – Published: 2026-03-23 20:30 – Updated: 2026-03-25 20:44
VLAI?
Summary
New API: IDOR in VideoProxy allows cross-user video content access via missing ownership check
Details

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:

task, exists, err := model.GetByOnlyTaskId(taskID)

GetByOnlyTaskId performs a database lookup using only task_id:

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:

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

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:

userId := c.GetInt("id")
task, exists, err := model.GetByTaskId(userId, taskID)
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/QuantumNous/new-api"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.11.4-alpha.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-30886"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-23T20:30:57Z",
    "nvd_published_at": "2026-03-23T20:16:25Z",
    "severity": "MODERATE"
  },
  "details": "## Summary\n\nThe 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\u0027s `task_id` can retrieve that user\u0027s generated video content because the handler queries tasks by `task_id` alone and does not verify ownership.\n\n## Affected Component\n\n- Endpoint: `GET /v1/videos/:task_id/content`\n- Route middleware: `TokenOrUserAuth()`\n- Vulnerable handler: `controller.VideoProxy`\n\n## Details\n\n`VideoProxy` fetches the task with:\n\n```go\ntask, exists, err := model.GetByOnlyTaskId(taskID)\n```\n\n`GetByOnlyTaskId` performs a database lookup using only `task_id`:\n\n```go\nerr = DB.Where(\"task_id = ?\", taskId).First(\u0026task).Error\n```\n\nThe authenticated user\u0027s ID is available in request context, but `VideoProxy` does not use it. This allows any authenticated user to request `/v1/videos/\u003cforeign_task_id\u003e/content` and access another user\u0027s video if they know a valid task ID.\n\nOther task-fetch paths already enforce ownership correctly via:\n\n```go\nmodel.GetByTaskId(userId, taskId)\n```\n\n## Impact\n\nAn authenticated attacker who knows another user\u0027s `task_id` can:\n\n- Download video content belonging to another user\n- Bypass tenant isolation for generated media assets\n- Cause the server to fetch upstream video content for a task the attacker does not own\n\nFor 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.\n\n## Proof of Concept\n\n```bash\ncurl -o stolen_video.mp4 \\\n  \"https://\u003cinstance\u003e/v1/videos/\u003cvictim_task_id\u003e/content\" \\\n  -H \"Authorization: Bearer sk-\u003cattacker_token\u003e\"\n```\n\nExpected result:\n\n- Response returns `200 OK`\n- Response body contains the victim\u0027s video content\n\n## Recommended Fix\n\nReplace the task lookup in `VideoProxy` with an ownership-checked query:\n\n```go\nuserId := c.GetInt(\"id\")\ntask, exists, err := model.GetByTaskId(userId, taskID)\n```",
  "id": "GHSA-f35r-v9x5-r8mc",
  "modified": "2026-03-25T20:44:47Z",
  "published": "2026-03-23T20:30:57Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/QuantumNous/new-api/security/advisories/GHSA-f35r-v9x5-r8mc"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-30886"
    },
    {
      "type": "WEB",
      "url": "https://github.com/QuantumNous/new-api/commit/50ec2bac6b341e651fc9ac4344e3bd2cdaeafdbd"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/QuantumNous/new-api"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "New API: IDOR in VideoProxy allows cross-user video content access via missing ownership check "
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.


Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…