Common Weakness Enumeration

CWE-639

Allowed

Authorization Bypass Through User-Controlled Key

Abstraction: Base · Status: Incomplete

The system's authorization functionality does not prevent one user from gaining access to another user's data or record by modifying the key value identifying the data.

3381 vulnerabilities reference this CWE, most recent first.

GHSA-748W-HM6R-QC7V

Vulnerability from github – Published: 2026-05-15 18:01 – Updated: 2026-06-11 13:30
VLAI
Summary
Authenticated Sharp users can download unrelated Laravel Storage objects through the generic download endpoint
Details

Sharp exposes a generic download endpoint that authorizes access only to the supplied Sharp entity instance, but then reads the target storage disk and path from request parameters.

Because the requested storage object is not bound to the authorized entity instance, an authenticated Sharp user who can view one valid record may use that record as an authorization anchor to download unrelated disk-relative objects from configured Laravel Storage disks.

The confirmed impact is authenticated disclosure of unrelated objects from configured Laravel Storage disks. This issue does not imply arbitrary host filesystem access outside configured Laravel Storage disk roots.

Impact

An authenticated Sharp user with view access to at least one valid Sharp entity instance may be able to download unrelated files from configured Laravel Storage disks by supplying a different disk and path to the generic download endpoint.

Depending on the application, exposed files may include exports, backups, invoices, internal documents, uploads belonging to other records, tenant-specific data, or operational files stored on private application disks.

The attacker does not need authorization to the storage object being downloaded. They only need an authenticated Sharp session and view access to one valid entity instance that can be used as the authorization anchor.

Attack requirements

An attacker must have:

  • an authenticated Sharp session
  • view access to at least one valid Sharp entity instance

The attacker does not need authorization to the storage object being downloaded.

Affected endpoint

GET /sharp/{globalFilter}/download/{entityKey}/{instanceId?}

Patches

After the fix, requests to the generic download endpoint without a valid signature are rejected. Modifying the disk, path, entityKey, or instanceId parameters of a Sharp-generated download URL invalidates the signature and prevents the modified request from being used to download another storage object.

Workarounds

If upgrading is not immediately possible, applications should restrict downloads.allowed_disks to the smallest possible set of disks required by Sharp downloads.

Applications should also avoid storing sensitive unrelated files on disks reachable by Sharp’s generic download endpoint, and should add application-level controls to ensure that requested files are bound to the authorized record.

Disk allowlisting reduces the reachable storage surface, but it does not fully fix the missing per-record file binding. Upgrading to a patched version is recommended.

Resources

  • Laravel signed URLs documentation: https://laravel.com/docs/urls#signed-urls
  • CWE-639: https://cwe.mitre.org/data/definitions/639.html
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "code16/sharp"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "9.22.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-44692"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-15T18:01:03Z",
    "nvd_published_at": "2026-06-10T22:16:57Z",
    "severity": "HIGH"
  },
  "details": "Sharp exposes a generic download endpoint that authorizes access only to the supplied Sharp entity instance, but then reads the target storage `disk` and `path` from request parameters.\n\nBecause the requested storage object is not bound to the authorized entity instance, an authenticated Sharp user who can view one valid record may use that record as an authorization anchor to download unrelated disk-relative objects from configured Laravel Storage disks.\n\nThe confirmed impact is authenticated disclosure of unrelated objects from configured Laravel Storage disks. This issue does not imply arbitrary host filesystem access outside configured Laravel Storage disk roots.\n\n### Impact\n\nAn authenticated Sharp user with view access to at least one valid Sharp entity instance may be able to download unrelated files from configured Laravel Storage disks by supplying a different `disk` and `path` to the generic download endpoint.\n\nDepending on the application, exposed files may include exports, backups, invoices, internal documents, uploads belonging to other records, tenant-specific data, or operational files stored on private application disks.\n\nThe attacker does not need authorization to the storage object being downloaded. They only need an authenticated Sharp session and view access to one valid entity instance that can be used as the authorization anchor.\n\n### Attack requirements\n\nAn attacker must have:\n\n- an authenticated Sharp session\n- view access to at least one valid Sharp entity instance\n\nThe attacker does not need authorization to the storage object being downloaded.\n\n### Affected endpoint\n\n`GET /sharp/{globalFilter}/download/{entityKey}/{instanceId?}`\n\n### Patches\n\nAfter the fix, requests to the generic download endpoint without a valid signature are rejected. Modifying the `disk`, `path`, `entityKey`, or `instanceId` parameters of a Sharp-generated download URL invalidates the signature and prevents the modified request from being used to download another storage object.\n\n### Workarounds\n\nIf upgrading is not immediately possible, applications should restrict `downloads.allowed_disks` to the smallest possible set of disks required by Sharp downloads.\n\nApplications should also avoid storing sensitive unrelated files on disks reachable by Sharp\u2019s generic download endpoint, and should add application-level controls to ensure that requested files are bound to the authorized record.\n\nDisk allowlisting reduces the reachable storage surface, but it does not fully fix the missing per-record file binding. Upgrading to a patched version is recommended.\n\n### Resources\n\n- Laravel signed URLs documentation: https://laravel.com/docs/urls#signed-urls\n- CWE-639: https://cwe.mitre.org/data/definitions/639.html",
  "id": "GHSA-748w-hm6r-qc7v",
  "modified": "2026-06-11T13:30:32Z",
  "published": "2026-05-15T18:01:03Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/code16/sharp/security/advisories/GHSA-748w-hm6r-qc7v"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-44692"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/code16/sharp"
    },
    {
      "type": "WEB",
      "url": "https://github.com/code16/sharp/releases/tag/v9.22.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Authenticated Sharp users can download unrelated Laravel Storage objects through the generic download endpoint"
}

GHSA-74H3-CXQ7-VC5Q

Vulnerability from github – Published: 2026-07-24 17:01 – Updated: 2026-07-24 17:01
VLAI
Summary
Open WebUI: Cross-user code-interpreter and tool execution via unvalidated Socket.IO event-caller session_id
Details

Summary

An authenticated low-privilege user can execute arbitrary code-interpreter Python and tools inside another user's authenticated session. The Socket.IO event-caller (get_event_call) delivers execute:python / execute:tool events to a client-supplied session_id after only checking that the session is connected, never that it belongs to the requester. Combined with ydoc:document:join, which exposes the live socket ids of everyone in a shared note's collaboration room to any read-access participant, an attacker can target a victim's session and run attacker-chosen code/tools in the victim's browser context. When the victim is an administrator, that hijacked context reaches the admin-only Functions API, whose source is executed server-side, yielding remote code execution as the server process (root in the default container).

Affected component

  • backend/open_webui/socket/main.pyget_event_call() / __event_caller__
  • backend/open_webui/main.py — chat-completion metadata (session_id taken from the request body)

Root cause

The event-caller routes to a caller-controlled session id with no ownership check:

# backend/open_webui/socket/main.py — get_event_call()
async def __event_caller__(event_data):
    session_id = request_info['session_id']
    if session_id not in SESSION_POOL:                 # only checks the session is connected
        return {'error': 'Client session disconnected.'}
    return await sio.call('events', {...}, to=session_id, ...)   # delivered to that sid

session_id originates from the request body and is never validated against the authenticated user:

# backend/open_webui/main.py
metadata = {
    'user_id': user.id,                               # server-derived (trustworthy)
    'session_id': form_data.pop('session_id', None),  # client-controlled
    ...
}

SESSION_POOL[session_id] is the user record of whoever owns that socket. Because the caller checks only membership (in SESSION_POOL), a request carrying another user's session_id causes execute:python / execute:tool to be delivered to that other user's browser.

Reachability

  • execute:python / execute:tool are emitted from the code-interpreter and tool-call paths (utils/middleware.py, tools/builtin.py), all routed through get_event_call.
  • The victim's live session_id is disclosed to any read-access participant of a shared note via ydoc:document:join.
  • POST /api/v1/chat/completions requires only get_verified_user (the default user role). The attacker uses their own account and a model / Direct Connection they control to choose the payload.

Impact

  • Any victim: arbitrary code-interpreter Python and tool execution in the victim's authenticated session — the attacker acts with the victim's identity and origin (full session/account compromise).
  • Admin victim: the hijacked admin context reaches POST /api/v1/functions/create, whose source is exec()'d server-side → remote code execution as the server process (root in the default container).

The Functions API is intended administrator code-execution; the vulnerability here is the cross-user delivery that lets an attacker drive another user's session — including an admin's — into it. The primitive is a full session compromise even against non-admin victims.

Proof of Concept

The reporter's exploit.py reproduced on ghcr.io/open-webui/open-webui:0.9.6 and a build of the v0.9.6 tag, confirming blind server-side RCE out-of-band (callback returns uid=0(root)), using only a low-privilege user account that shared a note with an admin victim. Preconditions: code interpreter enabled; attacker shares a note with the victim; victim opens it while online; admin victim required for server RCE.

Fix

get_event_call must verify the target session belongs to the requesting user before delivering, not merely that it is connected:

session = SESSION_POOL.get(session_id)
if session is None or session.get('id') != request_info.get('user_id'):
    return {'error': 'Client session disconnected.'}

user_id in the request metadata is server-derived from the authenticated user, so it is trustworthy. Restricting ydoc:document:join so it does not disclose other participants' socket ids is recommended as defence-in-depth.

Affected / Patched

  • Affected: < 0.10.0 (last affected release 0.9.6)
  • Patched: v0.10.0. get_event_call now verifies the target session belongs to the requesting user before delivering (session is None or session.get('id') != request_info.get('user_id')), using the server-derived user_id from the request metadata. The recommended ydoc:document:join sid-disclosure restriction is defence-in-depth and independent of this fix; the ownership check closes the cross-user delivery regardless of whether the victim's sid is known.
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "open-webui"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.10.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-59216"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-200",
      "CWE-639",
      "CWE-862",
      "CWE-94"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-07-24T17:01:53Z",
    "nvd_published_at": "2026-07-09T17:17:02Z",
    "severity": "HIGH"
  },
  "details": "## Summary\n\nAn authenticated low-privilege user can execute arbitrary code-interpreter Python and tools inside **another** user\u0027s authenticated session. The Socket.IO event-caller (`get_event_call`) delivers `execute:python` / `execute:tool` events to a **client-supplied** `session_id` after only checking that the session is connected, never that it belongs to the requester. Combined with `ydoc:document:join`, which exposes the live socket ids of everyone in a shared note\u0027s collaboration room to any read-access participant, an attacker can target a victim\u0027s session and run attacker-chosen code/tools in the victim\u0027s browser context. When the victim is an administrator, that hijacked context reaches the admin-only Functions API, whose source is executed server-side, yielding remote code execution as the server process (root in the default container).\n\n## Affected component\n\n- `backend/open_webui/socket/main.py` \u2014 `get_event_call()` / `__event_caller__`\n- `backend/open_webui/main.py` \u2014 chat-completion metadata (`session_id` taken from the request body)\n\n## Root cause\n\nThe event-caller routes to a caller-controlled session id with no ownership check:\n\n```python\n# backend/open_webui/socket/main.py \u2014 get_event_call()\nasync def __event_caller__(event_data):\n    session_id = request_info[\u0027session_id\u0027]\n    if session_id not in SESSION_POOL:                 # only checks the session is connected\n        return {\u0027error\u0027: \u0027Client session disconnected.\u0027}\n    return await sio.call(\u0027events\u0027, {...}, to=session_id, ...)   # delivered to that sid\n```\n\n`session_id` originates from the request body and is never validated against the authenticated user:\n\n```python\n# backend/open_webui/main.py\nmetadata = {\n    \u0027user_id\u0027: user.id,                               # server-derived (trustworthy)\n    \u0027session_id\u0027: form_data.pop(\u0027session_id\u0027, None),  # client-controlled\n    ...\n}\n```\n\n`SESSION_POOL[session_id]` is the user record of whoever owns that socket. Because the caller checks only membership (`in SESSION_POOL`), a request carrying another user\u0027s `session_id` causes `execute:python` / `execute:tool` to be delivered to that other user\u0027s browser.\n\n## Reachability\n\n- `execute:python` / `execute:tool` are emitted from the code-interpreter and tool-call paths (`utils/middleware.py`, `tools/builtin.py`), all routed through `get_event_call`.\n- The victim\u0027s live `session_id` is disclosed to any read-access participant of a shared note via `ydoc:document:join`.\n- `POST /api/v1/chat/completions` requires only `get_verified_user` (the default user role). The attacker uses their own account and a model / Direct Connection they control to choose the payload.\n\n## Impact\n\n- **Any victim:** arbitrary code-interpreter Python and tool execution in the victim\u0027s authenticated session \u2014 the attacker acts with the victim\u0027s identity and origin (full session/account compromise).\n- **Admin victim:** the hijacked admin context reaches `POST /api/v1/functions/create`, whose source is `exec()`\u0027d server-side \u2192 remote code execution as the server process (root in the default container).\n\nThe Functions API is intended administrator code-execution; the vulnerability here is the cross-user delivery that lets an attacker drive another user\u0027s session \u2014 including an admin\u0027s \u2014 into it. The primitive is a full session compromise even against non-admin victims.\n\n## Proof of Concept\n\nThe reporter\u0027s `exploit.py` reproduced on `ghcr.io/open-webui/open-webui:0.9.6` and a build of the `v0.9.6` tag, confirming blind server-side RCE out-of-band (callback returns `uid=0(root)`), using only a low-privilege `user` account that shared a note with an admin victim. Preconditions: code interpreter enabled; attacker shares a note with the victim; victim opens it while online; admin victim required for server RCE.\n\n## Fix\n\n`get_event_call` must verify the target session belongs to the requesting user before delivering, not merely that it is connected:\n\n```python\nsession = SESSION_POOL.get(session_id)\nif session is None or session.get(\u0027id\u0027) != request_info.get(\u0027user_id\u0027):\n    return {\u0027error\u0027: \u0027Client session disconnected.\u0027}\n```\n\n`user_id` in the request metadata is server-derived from the authenticated user, so it is trustworthy. Restricting `ydoc:document:join` so it does not disclose other participants\u0027 socket ids is recommended as defence-in-depth.\n\n## Affected / Patched\n\n- Affected: `\u003c 0.10.0` (last affected release 0.9.6)\n- Patched: v0.10.0. `get_event_call` now verifies the target session belongs to the requesting user before delivering (`session is None or session.get(\u0027id\u0027) != request_info.get(\u0027user_id\u0027)`), using the server-derived `user_id` from the request metadata. The recommended `ydoc:document:join` sid-disclosure restriction is defence-in-depth and independent of this fix; the ownership check closes the cross-user delivery regardless of whether the victim\u0027s sid is known.",
  "id": "GHSA-74h3-cxq7-vc5q",
  "modified": "2026-07-24T17:01:53Z",
  "published": "2026-07-24T17:01:53Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/open-webui/open-webui/security/advisories/GHSA-74h3-cxq7-vc5q"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-59216"
    },
    {
      "type": "WEB",
      "url": "https://github.com/open-webui/open-webui/pull/25763"
    },
    {
      "type": "WEB",
      "url": "https://github.com/open-webui/open-webui/commit/386ac958144dbbbf0aa6e268070d72b681a318aa"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/open-webui/open-webui"
    },
    {
      "type": "WEB",
      "url": "https://github.com/open-webui/open-webui/releases/tag/v0.10.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:C/C:H/I:H/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Open WebUI: Cross-user code-interpreter and tool execution via unvalidated Socket.IO event-caller session_id"
}

GHSA-74W5-9874-X8HW

Vulnerability from github – Published: 2026-07-15 12:32 – Updated: 2026-07-15 12:32
VLAI
Details

Missing Authorization (CWE-862) in BankAccountListController (app/Http/Controllers/Api/BankAccount/BankAccountListController.php), exposed at GET /api/bank-account, in Prospero Flow CRM <5.5.3, which allows a remote, authenticated attacker holding a low-privileged role (e.g. the "User"/"Usuario" role) to read arbitrary bank account records belonging to their company by sending an authenticated request to the endpoint with a valid bearer token, because the API route is protected only by the auth:api middleware and carries no permission gate, unlike the equivalent web route, which enforces can('read bank'), and the handler resolves records with Account::where('company_id', Auth::user()->company_id)->get(), performing only company scoping and no role or permission check before returning the data. This results in the unauthorized disclosure of sensitive banking information (e.g. IBAN, SWIFT/BIC, account identifiers) to users who should not have access to it.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-59235"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-07-15T11:16:33Z",
    "severity": "HIGH"
  },
  "details": "Missing Authorization (CWE-862) in BankAccountListController (app/Http/Controllers/Api/BankAccount/BankAccountListController.php), exposed at GET /api/bank-account, in Prospero Flow CRM \u003c5.5.3, which allows a remote, authenticated attacker holding a low-privileged role (e.g. the \"User\"/\"Usuario\" role) to read arbitrary bank account records belonging to their company by sending an authenticated request to the endpoint with a valid bearer token, because the API route is protected only by the auth:api middleware and carries no permission gate, unlike the equivalent web route, which enforces can(\u0027read bank\u0027), and the handler resolves records with Account::where(\u0027company_id\u0027, Auth::user()-\u003ecompany_id)-\u003eget(), performing only company scoping and no role or permission check before returning the data. This results in the unauthorized disclosure of sensitive banking information (e.g. IBAN, SWIFT/BIC, account identifiers) to users who should not have access to it.",
  "id": "GHSA-74w5-9874-x8hw",
  "modified": "2026-07-15T12:32:02Z",
  "published": "2026-07-15T12:32:01Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-59235"
    },
    {
      "type": "WEB",
      "url": "https://github.com/Roskus/prospero-flow-crm/commit/57bb57212af03151c989d67d6723d5ddb3e81e7b"
    },
    {
      "type": "WEB",
      "url": "https://github.com/Roskus/prospero-flow-crm/releases#release-v5.5.3"
    },
    {
      "type": "WEB",
      "url": "https://secur0.com/en/cna/cve-list/cve-2026-59235-missing-authorization-in-prospero-flow-crm-allows-low-privileged-users-to-read-all-bank-accounts"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-74XR-GJ9J-429C

Vulnerability from github – Published: 2024-10-04 15:31 – Updated: 2024-10-16 18:31
VLAI
Details

This vulnerability exists in the Shilpi Net Back Office due to improper access controls on certain API endpoints. An authenticated remote attacker could exploit this vulnerability by manipulating a parameter dfclientid through API request URLs which could lead to unauthorized access to sensitive information belonging to other users.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-47657"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-10-04T13:15:12Z",
    "severity": "HIGH"
  },
  "details": "This vulnerability exists in the Shilpi Net Back Office due to improper access controls on certain API endpoints. An authenticated remote attacker could exploit this vulnerability by manipulating a parameter dfclientid through API request URLs which could lead to unauthorized access to sensitive information belonging to other users.",
  "id": "GHSA-74xr-gj9j-429c",
  "modified": "2024-10-16T18:31:34Z",
  "published": "2024-10-04T15:31:21Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-47657"
    },
    {
      "type": "WEB",
      "url": "https://www.cert-in.org.in/s2cMainServlet?pageid=PUBVLNOTES01\u0026VLCODE=CIVN-2024-0313"
    }
  ],
  "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"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:L/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-753F-JPP4-MP46

Vulnerability from github – Published: 2025-04-16 00:31 – Updated: 2025-04-16 00:31
VLAI
Details

An unauthenticated attackers can obtain a list of smart devices by knowing a valid username through an unprotected API.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-27927"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-04-15T22:15:25Z",
    "severity": "MODERATE"
  },
  "details": "An unauthenticated attackers can obtain a list of smart devices by knowing a valid username through an unprotected API.",
  "id": "GHSA-753f-jpp4-mp46",
  "modified": "2025-04-16T00:31:37Z",
  "published": "2025-04-16T00:31:37Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-27927"
    },
    {
      "type": "WEB",
      "url": "https://www.cisa.gov/news-events/ics-advisories/icsa-25-105-04"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-756Q-GQ9H-FP22

Vulnerability from github – Published: 2026-04-29 21:21 – Updated: 2026-05-08 01:31
VLAI
Summary
n8n has Public API Variables IDOR that Allows Cross-Project Secret Disclosure
Details

Impact

An authenticated user with a valid API key scoped to variable:list could read variables from projects they are not a member of by supplying an arbitrary projectId query parameter to the public API variables endpoint. The handler queried the variables repository directly without enforcing project membership checks, bypassing the authorization-aware service layer used by the internal enterprise controller.

If variables were misused to store sensitive information such as credentials or tokens, they should be rotated immediately.

This issue only affects licensed enterprise or team deployments with multiple projects and the variables feature enabled.

Patches

The issue has been fixed in n8n versions 1.123.32, 2.17.4, and 2.18.1. Users should upgrade to one of these versions or later to remediate the vulnerability.

Workarounds

If upgrading is not immediately possible, administrators should consider the following temporary mitigations:

  • Restrict n8n access and API key issuance to fully trusted users only.
  • Audit existing project variables for sensitive values and rotate any secrets that may have been exposed.

These workarounds do not fully remediate the risk and should only be used as short-term mitigation measures.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "n8n"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.123.32"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "n8n"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.18.0"
            },
            {
              "fixed": "2.18.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "n8n"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.0.0"
            },
            {
              "fixed": "2.17.4"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-42227"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-04-29T21:21:00Z",
    "nvd_published_at": "2026-05-04T19:16:04Z",
    "severity": "MODERATE"
  },
  "details": "## Impact\nAn authenticated user with a valid API key scoped to `variable:list` could read variables from projects they are not a member of by supplying an arbitrary `projectId` query parameter to the public API variables endpoint. The handler queried the variables repository directly without enforcing project membership checks, bypassing the authorization-aware service layer used by the internal enterprise controller. \n\nIf variables were misused to store sensitive information such as credentials or tokens, they should be rotated immediately.\n\nThis issue only affects licensed enterprise or team deployments with multiple projects and the variables feature enabled.\n\n## Patches\nThe issue has been fixed in n8n versions 1.123.32, 2.17.4, and 2.18.1. Users should upgrade to one of these versions or later to remediate the vulnerability.\n\n## Workarounds\nIf upgrading is not immediately possible, administrators should consider the following temporary mitigations:\n\n- Restrict n8n access and API key issuance to fully trusted users only.\n- Audit existing project variables for sensitive values and rotate any secrets that may have been exposed.\n\nThese workarounds do not fully remediate the risk and should only be used as short-term mitigation measures.",
  "id": "GHSA-756q-gq9h-fp22",
  "modified": "2026-05-08T01:31:18Z",
  "published": "2026-04-29T21:21:00Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/n8n-io/n8n/security/advisories/GHSA-756q-gq9h-fp22"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-42227"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/n8n-io/n8n"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "n8n has Public API Variables IDOR that Allows Cross-Project Secret Disclosure"
}

GHSA-75MG-988W-FM95

Vulnerability from github – Published: 2026-05-26 13:30 – Updated: 2026-05-26 13:30
VLAI
Details

Authorization bypass in the entry duplication feature in Devolutions Server allows an authenticated user with write access to any vault to copy documentation and attachments from an entry in a vault they cannot access via a crafted save request.

This issue affects :

  • Devolutions Server 2026.1.6.0 through 2026.1.16.0
  • Devolutions Server 2025.3.20.0 and earlier
Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-9248"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-05-22T16:16:25Z",
    "severity": "LOW"
  },
  "details": "Authorization bypass in the entry duplication feature in Devolutions Server allows an authenticated user with write access to any vault to copy documentation and attachments from an entry in a vault they cannot access via a crafted save request.\n\nThis issue affects :\n\n  *  Devolutions Server 2026.1.6.0 through 2026.1.16.0\n  *  Devolutions Server 2025.3.20.0 and earlier",
  "id": "GHSA-75mg-988w-fm95",
  "modified": "2026-05-26T13:30:19Z",
  "published": "2026-05-26T13:30:19Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-9248"
    },
    {
      "type": "WEB",
      "url": "https://devolutions.net/security/advisories/DEVO-2026-0013"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-75P6-52G3-RQC8

Vulnerability from github – Published: 2022-04-26 21:21 – Updated: 2022-07-21 16:21
VLAI
Summary
Keycloak vulnerable to privilege escalation on Token Exchange feature
Details

A privilege escalation flaw was found in the token exchange feature of keycloak. Missing authorization allows a client application holding a valid access token to exchange tokens for any target client by passing the client_id of the target. This could allow a client to gain unauthorized access to additional services.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Maven",
        "name": "org.keycloak:keycloak-services"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "18.0.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2022-1245"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639",
      "CWE-862",
      "CWE-863"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2022-04-26T21:21:00Z",
    "nvd_published_at": "2022-07-08T00:15:00Z",
    "severity": "CRITICAL"
  },
  "details": "A privilege escalation flaw was found in the token exchange feature of keycloak. Missing authorization allows a client application holding a valid access token to exchange tokens for any target client by passing the client_id of the target. This could allow a client to gain unauthorized access to additional services.",
  "id": "GHSA-75p6-52g3-rqc8",
  "modified": "2022-07-21T16:21:16Z",
  "published": "2022-04-26T21:21:00Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/keycloak/keycloak/security/advisories/GHSA-75p6-52g3-rqc8"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-1245"
    },
    {
      "type": "WEB",
      "url": "https://github.com/keycloak/keycloak/commit/76d83f46fad94ebcbedaa49e6daad458e2894e52"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/keycloak/keycloak"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Keycloak vulnerable to privilege escalation on Token Exchange feature"
}

GHSA-75Q5-8JHM-6829

Vulnerability from github – Published: 2024-08-16 15:31 – Updated: 2024-08-28 21:31
VLAI
Details

Authorization Bypass Through User-Controlled Key vulnerability in upKeeper Solutions product upKeeper Manager allows Utilizing REST's Trust in the System Resource to Obtain Sensitive Data.This issue affects upKeeper Manager: through 5.1.9.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-42464"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-08-16T14:15:13Z",
    "severity": "HIGH"
  },
  "details": "Authorization Bypass Through User-Controlled Key vulnerability in upKeeper Solutions product upKeeper Manager allows Utilizing REST\u0027s Trust in the System Resource to Obtain Sensitive Data.This issue affects upKeeper Manager: through 5.1.9.",
  "id": "GHSA-75q5-8jhm-6829",
  "modified": "2024-08-28T21:31:27Z",
  "published": "2024-08-16T15:31:41Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-42464"
    },
    {
      "type": "WEB",
      "url": "https://support.upkeeper.se/hc/en-us/articles/15432275702044-CVE-2024-42464-Leak-of-user-Information"
    }
  ],
  "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"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-75QQ-68M8-PVFR

Vulnerability from github – Published: 2026-03-26 18:05 – Updated: 2026-03-27 21:37
VLAI
Summary
AVideo: Unauthenticated IDOR in playlistsVideos.json.php Exposes Private Playlist Contents
Details

Summary

The objects/playlistsVideos.json.php endpoint returns the full video contents of any playlist by ID without any authentication or authorization check. Private playlists (including watch_later and favorite types) are correctly hidden from listing endpoints via playlistsFromUser.json.php, but their contents are directly accessible through this endpoint by providing the sequential integer playlists_id parameter.

Details

The endpoint at objects/playlistsVideos.json.php accepts a playlists_id parameter and directly calls PlayList::getVideosFromPlaylist() with no ownership or visibility validation:

// objects/playlistsVideos.json.php:24-28
if (empty($_REQUEST['playlists_id'])) {
    die('Play List can not be empty');
}
require_once './playlist.php';
$videos = PlayList::getVideosFromPlaylist($_REQUEST['playlists_id']);

The getVideosFromPlaylist() method at objects/playlist.php:588 performs a SQL query joining playlists_has_videos, videos, and users tables with no authorization filter:

// objects/playlist.php:592-597
$sql = "SELECT v.*, p.*,v.created as cre, p.`order` as video_order  "
    . " FROM  playlists_has_videos p "
    . " LEFT JOIN videos as v ON videos_id = v.id "
    . " LEFT JOIN users u ON u.id = v.users_id "
    . " WHERE playlists_id = ? AND v.status != 'i' ";

In contrast, the listing endpoint playlistsFromUser.json.php correctly enforces visibility at lines 23-27:

// objects/playlistsFromUser.json.php:23-27
$publicOnly = true;
if (User::isLogged() && (User::getId() == $requestedUserId || User::isAdmin())) {
    $publicOnly = false;
}
$row = PlayList::getAllFromUser($requestedUserId, $publicOnly);

This creates a bypass: even though private playlists are hidden from listing, their contents are fully exposed via the videos endpoint. Playlist IDs are sequential integers, making enumeration trivial. The .htaccess rewrite at line 356 maps the clean URL playListsVideos.json to this endpoint.

PoC

Step 1: Enumerate playlist contents without authentication

# No cookies or auth headers needed. Increment playlists_id to enumerate.
curl -s "http://TARGET/objects/playlistsVideos.json.php?playlists_id=1" | python3 -m json.tool

Expected: Returns full video metadata array for playlist ID 1, including video titles, filenames, URLs, user info, comments, and subscriber counts.

Step 2: Enumerate private playlists (watch_later, favorite)

# Iterate through sequential IDs to find private playlists
for i in $(seq 1 50); do
  result=$(curl -s "http://TARGET/objects/playlistsVideos.json.php?playlists_id=$i")
  count=$(echo "$result" | python3 -c "import sys,json; print(len(json.load(sys.stdin)))" 2>/dev/null)
  if [ "$count" != "0" ] && [ -n "$count" ]; then
    echo "Playlist $i: $count videos"
  fi
done

Step 3: Confirm the listing endpoint correctly hides private playlists

# This correctly returns only public playlists for user 1
curl -s "http://TARGET/objects/playlistsFromUser.json.php?users_id=1" | python3 -m json.tool
# Compare: playlistsVideos.json.php returns contents of ALL playlists including private ones

Impact

An unauthenticated attacker can:

  • Enumerate all users' watch history by accessing watch_later playlist contents
  • Enumerate all users' favorites by accessing favorite playlist contents
  • Access unlisted/private custom playlists that were intentionally hidden from public view
  • Harvest video metadata including filenames, URLs, user information, and comments for videos in private playlists

This is a privacy violation that exposes user viewing habits and content preferences. The sequential integer IDs make bulk enumeration straightforward.

Recommended Fix

Add authorization checks to objects/playlistsVideos.json.php before returning playlist contents:

// objects/playlistsVideos.json.php — add after line 27, before getVideosFromPlaylist()
require_once $global['systemRootPath'] . 'plugin/PlayLists/PlayLists.php';

$pl = new PlayList($_REQUEST['playlists_id']);
$plStatus = $pl->getStatus();

// Public playlists are accessible to everyone
if ($plStatus !== 'public') {
    // Private, unlisted, watch_later, and favorite playlists require ownership or admin
    if (!User::isLogged() || (User::getId() != $pl->getUsers_id() && !User::isAdmin())) {
        header('HTTP/1.1 403 Forbidden');
        die(json_encode(['error' => 'You do not have permission to view this playlist']));
    }
}

$videos = PlayList::getVideosFromPlaylist($_REQUEST['playlists_id']);
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "wwbn/avideo"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "last_affected": "26.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-33759"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639",
      "CWE-862"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-26T18:05:40Z",
    "nvd_published_at": "2026-03-27T15:16:58Z",
    "severity": "MODERATE"
  },
  "details": "## Summary\n\nThe `objects/playlistsVideos.json.php` endpoint returns the full video contents of any playlist by ID without any authentication or authorization check. Private playlists (including `watch_later` and `favorite` types) are correctly hidden from listing endpoints via `playlistsFromUser.json.php`, but their contents are directly accessible through this endpoint by providing the sequential integer `playlists_id` parameter.\n\n## Details\n\nThe endpoint at `objects/playlistsVideos.json.php` accepts a `playlists_id` parameter and directly calls `PlayList::getVideosFromPlaylist()` with no ownership or visibility validation:\n\n```php\n// objects/playlistsVideos.json.php:24-28\nif (empty($_REQUEST[\u0027playlists_id\u0027])) {\n    die(\u0027Play List can not be empty\u0027);\n}\nrequire_once \u0027./playlist.php\u0027;\n$videos = PlayList::getVideosFromPlaylist($_REQUEST[\u0027playlists_id\u0027]);\n```\n\nThe `getVideosFromPlaylist()` method at `objects/playlist.php:588` performs a SQL query joining `playlists_has_videos`, `videos`, and `users` tables with no authorization filter:\n\n```php\n// objects/playlist.php:592-597\n$sql = \"SELECT v.*, p.*,v.created as cre, p.`order` as video_order  \"\n    . \" FROM  playlists_has_videos p \"\n    . \" LEFT JOIN videos as v ON videos_id = v.id \"\n    . \" LEFT JOIN users u ON u.id = v.users_id \"\n    . \" WHERE playlists_id = ? AND v.status != \u0027i\u0027 \";\n```\n\nIn contrast, the listing endpoint `playlistsFromUser.json.php` correctly enforces visibility at lines 23-27:\n\n```php\n// objects/playlistsFromUser.json.php:23-27\n$publicOnly = true;\nif (User::isLogged() \u0026\u0026 (User::getId() == $requestedUserId || User::isAdmin())) {\n    $publicOnly = false;\n}\n$row = PlayList::getAllFromUser($requestedUserId, $publicOnly);\n```\n\nThis creates a bypass: even though private playlists are hidden from listing, their contents are fully exposed via the videos endpoint. Playlist IDs are sequential integers, making enumeration trivial. The `.htaccess` rewrite at line 356 maps the clean URL `playListsVideos.json` to this endpoint.\n\n## PoC\n\n**Step 1: Enumerate playlist contents without authentication**\n\n```bash\n# No cookies or auth headers needed. Increment playlists_id to enumerate.\ncurl -s \"http://TARGET/objects/playlistsVideos.json.php?playlists_id=1\" | python3 -m json.tool\n```\n\nExpected: Returns full video metadata array for playlist ID 1, including video titles, filenames, URLs, user info, comments, and subscriber counts.\n\n**Step 2: Enumerate private playlists (watch_later, favorite)**\n\n```bash\n# Iterate through sequential IDs to find private playlists\nfor i in $(seq 1 50); do\n  result=$(curl -s \"http://TARGET/objects/playlistsVideos.json.php?playlists_id=$i\")\n  count=$(echo \"$result\" | python3 -c \"import sys,json; print(len(json.load(sys.stdin)))\" 2\u003e/dev/null)\n  if [ \"$count\" != \"0\" ] \u0026\u0026 [ -n \"$count\" ]; then\n    echo \"Playlist $i: $count videos\"\n  fi\ndone\n```\n\n**Step 3: Confirm the listing endpoint correctly hides private playlists**\n\n```bash\n# This correctly returns only public playlists for user 1\ncurl -s \"http://TARGET/objects/playlistsFromUser.json.php?users_id=1\" | python3 -m json.tool\n# Compare: playlistsVideos.json.php returns contents of ALL playlists including private ones\n```\n\n## Impact\n\nAn unauthenticated attacker can:\n\n- **Enumerate all users\u0027 watch history** by accessing `watch_later` playlist contents\n- **Enumerate all users\u0027 favorites** by accessing `favorite` playlist contents\n- **Access unlisted/private custom playlists** that were intentionally hidden from public view\n- **Harvest video metadata** including filenames, URLs, user information, and comments for videos in private playlists\n\nThis is a privacy violation that exposes user viewing habits and content preferences. The sequential integer IDs make bulk enumeration straightforward.\n\n## Recommended Fix\n\nAdd authorization checks to `objects/playlistsVideos.json.php` before returning playlist contents:\n\n```php\n// objects/playlistsVideos.json.php \u2014 add after line 27, before getVideosFromPlaylist()\nrequire_once $global[\u0027systemRootPath\u0027] . \u0027plugin/PlayLists/PlayLists.php\u0027;\n\n$pl = new PlayList($_REQUEST[\u0027playlists_id\u0027]);\n$plStatus = $pl-\u003egetStatus();\n\n// Public playlists are accessible to everyone\nif ($plStatus !== \u0027public\u0027) {\n    // Private, unlisted, watch_later, and favorite playlists require ownership or admin\n    if (!User::isLogged() || (User::getId() != $pl-\u003egetUsers_id() \u0026\u0026 !User::isAdmin())) {\n        header(\u0027HTTP/1.1 403 Forbidden\u0027);\n        die(json_encode([\u0027error\u0027 =\u003e \u0027You do not have permission to view this playlist\u0027]));\n    }\n}\n\n$videos = PlayList::getVideosFromPlaylist($_REQUEST[\u0027playlists_id\u0027]);\n```",
  "id": "GHSA-75qq-68m8-pvfr",
  "modified": "2026-03-27T21:37:49Z",
  "published": "2026-03-26T18:05:40Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/WWBN/AVideo/security/advisories/GHSA-75qq-68m8-pvfr"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-33759"
    },
    {
      "type": "WEB",
      "url": "https://github.com/WWBN/AVideo/commit/bb716fbece656c9fe39784f11e4e822b5867f1ca"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/WWBN/AVideo"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "AVideo: Unauthenticated IDOR in playlistsVideos.json.php Exposes Private Playlist Contents"
}

Mitigation
Architecture and Design

For each and every data access, ensure that the user has sufficient privilege to access the record that is being requested.

Mitigation
Architecture and Design Implementation

Make sure that the key that is used in the lookup of a specific user's record is not controllable externally by the user or that any tampering can be detected.

Mitigation
Architecture and Design

Use encryption in order to make it more difficult to guess other legitimate values of the key or associate a digital signature with the key so that the server can verify that there has been no tampering.

No CAPEC attack patterns related to this CWE.