CWE-639
AllowedAuthorization 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.
3255 vulnerabilities reference this CWE, most recent first.
GHSA-CP4F-5M9R-5JC2
Vulnerability from github – Published: 2026-06-01 14:19 – Updated: 2026-06-01 14:19Summary
Type: Insecure Direct Object Reference. The comment endpoints (POST /workspaces/{workspace_id}/issues/{issue_id}/comments and GET .../comments) gate access on require_workspace_member(workspace_id) only, then call CommentService.create(issue_id=issue_id, ...) and CommentService.list_for_issue(issue_id) without verifying that issue_id belongs to workspace_id. A user who is a member of any workspace W1 can read every comment on, and post new comments to, any issue in any other workspace W2.
File: src/praisonai-platform/praisonai_platform/api/routes/issues.py, lines 143-171; src/praisonai-platform/praisonai_platform/services/comment_service.py, lines 19-53.
Root cause: the route extracts workspace_id from the URL path and uses it solely for the membership gate, then passes the URL-supplied issue_id straight into CommentService without confirming that this issue exists in workspace_id. CommentService.list_for_issue(issue_id) runs SELECT * FROM comments WHERE issue_id = :issue_id with no workspace join. CommentService.create(issue_id=issue_id, ...) blindly writes a row with that issue_id. Both flows trust the URL-supplied issue ID as authoritative even though the membership check guarantees nothing about it.
Affected Code
File 1: src/praisonai-platform/praisonai_platform/api/routes/issues.py, lines 143-171.
@router.post("/{issue_id}/comments", response_model=CommentResponse, status_code=status.HTTP_201_CREATED)
async def add_comment(
workspace_id: str,
issue_id: str,
body: CommentCreate,
user: AuthIdentity = Depends(require_workspace_member), # only checks attacker is in workspace_id
session: AsyncSession = Depends(get_db),
):
svc = CommentService(session)
comment = await svc.create(
issue_id=issue_id, # <-- BUG: no validation that issue_id is in workspace_id
author_id=user.id,
content=body.content,
author_type="member" if user.is_user else "agent",
parent_id=body.parent_id,
)
return CommentResponse.model_validate(comment)
@router.get("/{issue_id}/comments", response_model=List[CommentResponse])
async def list_comments(
workspace_id: str,
issue_id: str,
user: AuthIdentity = Depends(require_workspace_member),
session: AsyncSession = Depends(get_db),
):
svc = CommentService(session)
comments = await svc.list_for_issue(issue_id) # <-- BUG: returns comments on any issue
return [CommentResponse.model_validate(c) for c in comments]
File 2: src/praisonai-platform/praisonai_platform/services/comment_service.py, lines 19-53.
class CommentService:
...
async def create(
self,
issue_id: str,
author_id: str,
content: str,
author_type: str = "member",
comment_type: str = "comment",
parent_id: Optional[str] = None,
) -> Comment:
comment = Comment(
issue_id=issue_id, # <-- accepts any issue_id; no workspace verify
author_type=author_type,
author_id=author_id,
...
)
self._session.add(comment)
await self._session.flush()
return comment
async def list_for_issue(self, issue_id: str) -> list[Comment]:
stmt = (
select(Comment)
.where(Comment.issue_id == issue_id) # <-- no JOIN against issues for workspace constraint
.order_by(Comment.created_at)
)
result = await self._session.execute(stmt)
return list(result.scalars().all())
Why it's wrong: the service trusts the caller-supplied issue_id as authoritative, but the route layer never verified that this issue belongs to the workspace the membership check covers. The standard FastAPI/SQLAlchemy fix is to first resolve the issue scoped to workspace_id (Issue.id = :issue_id AND Issue.workspace_id = :workspace_id) and only then proceed to comment operations. The MemberService.get(workspace_id, user_id) and LabelService.list_for_workspace(workspace_id) calls in the same codebase show the safe predicate; the comment service forgot to apply it.
Exploit Chain
- Attacker registers a workspace
W_attacker(member) and harvests a target issue UUIDI_Tfrom any side channel: agent prompts that mention issues, the activity feed (act_svc.logrecordsissue_id), webhook payloads, exported issue dumps, or simply by being a low-privilege observer of the attacker's own workspace whose internals reference foreign issue IDs (cross-workspace links, search across activity events). State: attacker holdsI_T. - Attacker authenticates and sends
GET /workspaces/W_attacker/issues/I_T/comments.require_workspace_member(W_attacker, attacker)passes (attacker is a member ofW_attacker). State: control flow enterslist_commentswithworkspace_id=W_attacker, issue_id=I_T. CommentService.list_for_issue(I_T)runsSELECT * FROM comments WHERE issue_id = 'I_T'with no workspace constraint. Every comment on the foreign issue is returned:content(often the most sensitive part of an issue tracker — bug-report repro steps with secrets, customer PII, internal triage notes),author_id,author_type,parent_id,created_at. State: response body is the full comment thread of the foreign issue.- Attacker repeats with
POST /workspaces/W_attacker/issues/I_T/commentsand a body of{"content": "<malicious>"}.CommentService.create(issue_id=I_T, author_id=attacker, ...)writes a row with the foreign issue's id and the attacker'sauthor_id. State: a new comment authored by the attacker appears in the foreign workspace's issue thread, indistinguishable to the foreign workspace's UI from a legitimate cross-workspace mention. Used at scale this becomes a comment-spam / phishing primitive (links in the comment body) targeting another tenant's users. - Final state: any attacker with one workspace-member token can exfiltrate every comment in the multi-tenant deployment given the issue UUIDs, and inject arbitrary comments under their own author identity into any foreign issue. The cross-workspace attribution gap is the worst part: the comment is recorded with the attacker's
author_id, but the foreign workspace has no member with that id and the foreign workspace's audit logs show no event (theact_svc.logcall inadd_commentis omitted).
Security Impact
Severity: sec-high. CVSS 7.6: network attack, low complexity, low privileges, no user interaction, scope unchanged, high confidentiality (full comment threads), high integrity (cross-workspace comment injection under attacker's own id), no availability claim.
Attacker capability: read every comment on every issue in the multi-tenant deployment given the issue UUIDs; post arbitrary comments under the attacker's identity into any foreign issue, allowing comment-spam, phishing-link injection into another tenant's UI, or social-engineering attribution attacks (the foreign workspace's UI renders a comment whose author belongs to no member of that workspace).
Preconditions: praisonai-platform is deployed multi-tenant; the attacker has any membership token; the target issue's UUID is known or guessable.
Differential: source-inspection-verified end-to-end. The asymmetry between CommentService.list_for_issue(issue_id) (no workspace predicate) and LabelService.list_for_workspace(workspace_id) (correctly workspace-scoped) confirms the gap. With the suggested fix below, every comment route first resolves the issue scoped to workspace_id, returns 404 if the issue is foreign, and only then proceeds.
Suggested Fix
Resolve the issue scoped to workspace_id at the route layer before dispatching to CommentService. This both fixes the read and the write paths and avoids changing the CommentService signature.
--- a/src/praisonai-platform/praisonai_platform/api/routes/issues.py
+++ b/src/praisonai-platform/praisonai_platform/api/routes/issues.py
@@ -141,6 +141,11 @@ async def delete_issue(...):
# ── Comments ─────────────────────────────────────────────────────────────────
+async def _require_issue_in_workspace(session, workspace_id: str, issue_id: str):
+ issue = await IssueService(session).get(workspace_id, issue_id) # workspace-scoped get (see companion advisory)
+ if issue is None:
+ raise HTTPException(status_code=404, detail="Issue not found")
+
@router.post("/{issue_id}/comments", response_model=CommentResponse, status_code=status.HTTP_201_CREATED)
async def add_comment(
workspace_id: str,
@@ -149,6 +154,7 @@ async def add_comment(
user: AuthIdentity = Depends(require_workspace_member),
session: AsyncSession = Depends(get_db),
):
+ await _require_issue_in_workspace(session, workspace_id, issue_id)
svc = CommentService(session)
comment = await svc.create(
issue_id=issue_id,
@@ -167,5 +173,6 @@ async def list_comments(
user: AuthIdentity = Depends(require_workspace_member),
session: AsyncSession = Depends(get_db),
):
+ await _require_issue_in_workspace(session, workspace_id, issue_id)
svc = CommentService(session)
comments = await svc.list_for_issue(issue_id)
Companion advisories file the same workspace-scoping gap for AgentService, IssueService, ProjectService, and LabelService. Each is a separate exploitable IDOR.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "praisonai-platform"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.1.4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-47417"
],
"database_specific": {
"cwe_ids": [
"CWE-639"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-01T14:19:33Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "## Summary\n\n**Type:** Insecure Direct Object Reference. The comment endpoints (`POST /workspaces/{workspace_id}/issues/{issue_id}/comments` and `GET .../comments`) gate access on `require_workspace_member(workspace_id)` only, then call `CommentService.create(issue_id=issue_id, ...)` and `CommentService.list_for_issue(issue_id)` without verifying that `issue_id` belongs to `workspace_id`. A user who is a member of any workspace `W1` can read every comment on, and post new comments to, any issue in any other workspace `W2`.\n**File:** `src/praisonai-platform/praisonai_platform/api/routes/issues.py`, lines 143-171; `src/praisonai-platform/praisonai_platform/services/comment_service.py`, lines 19-53.\n**Root cause:** the route extracts `workspace_id` from the URL path and uses it solely for the membership gate, then passes the URL-supplied `issue_id` straight into `CommentService` without confirming that this issue exists in `workspace_id`. `CommentService.list_for_issue(issue_id)` runs `SELECT * FROM comments WHERE issue_id = :issue_id` with no workspace join. `CommentService.create(issue_id=issue_id, ...)` blindly writes a row with that `issue_id`. Both flows trust the URL-supplied issue ID as authoritative even though the membership check guarantees nothing about it.\n\n## Affected Code\n\n**File 1:** `src/praisonai-platform/praisonai_platform/api/routes/issues.py`, lines 143-171.\n\n```python\n@router.post(\"/{issue_id}/comments\", response_model=CommentResponse, status_code=status.HTTP_201_CREATED)\nasync def add_comment(\n workspace_id: str,\n issue_id: str,\n body: CommentCreate,\n user: AuthIdentity = Depends(require_workspace_member), # only checks attacker is in workspace_id\n session: AsyncSession = Depends(get_db),\n):\n svc = CommentService(session)\n comment = await svc.create(\n issue_id=issue_id, # \u003c-- BUG: no validation that issue_id is in workspace_id\n author_id=user.id,\n content=body.content,\n author_type=\"member\" if user.is_user else \"agent\",\n parent_id=body.parent_id,\n )\n return CommentResponse.model_validate(comment)\n\n\n@router.get(\"/{issue_id}/comments\", response_model=List[CommentResponse])\nasync def list_comments(\n workspace_id: str,\n issue_id: str,\n user: AuthIdentity = Depends(require_workspace_member),\n session: AsyncSession = Depends(get_db),\n):\n svc = CommentService(session)\n comments = await svc.list_for_issue(issue_id) # \u003c-- BUG: returns comments on any issue\n return [CommentResponse.model_validate(c) for c in comments]\n```\n\n**File 2:** `src/praisonai-platform/praisonai_platform/services/comment_service.py`, lines 19-53.\n\n```python\nclass CommentService:\n ...\n\n async def create(\n self,\n issue_id: str,\n author_id: str,\n content: str,\n author_type: str = \"member\",\n comment_type: str = \"comment\",\n parent_id: Optional[str] = None,\n ) -\u003e Comment:\n comment = Comment(\n issue_id=issue_id, # \u003c-- accepts any issue_id; no workspace verify\n author_type=author_type,\n author_id=author_id,\n ...\n )\n self._session.add(comment)\n await self._session.flush()\n return comment\n\n async def list_for_issue(self, issue_id: str) -\u003e list[Comment]:\n stmt = (\n select(Comment)\n .where(Comment.issue_id == issue_id) # \u003c-- no JOIN against issues for workspace constraint\n .order_by(Comment.created_at)\n )\n result = await self._session.execute(stmt)\n return list(result.scalars().all())\n```\n\n**Why it\u0027s wrong:** the service trusts the caller-supplied `issue_id` as authoritative, but the route layer never verified that this issue belongs to the workspace the membership check covers. The standard FastAPI/SQLAlchemy fix is to first resolve the issue scoped to `workspace_id` (`Issue.id = :issue_id AND Issue.workspace_id = :workspace_id`) and only then proceed to comment operations. The `MemberService.get(workspace_id, user_id)` and `LabelService.list_for_workspace(workspace_id)` calls in the same codebase show the safe predicate; the comment service forgot to apply it.\n\n## Exploit Chain\n\n1. Attacker registers a workspace `W_attacker` (member) and harvests a target issue UUID `I_T` from any side channel: agent prompts that mention issues, the activity feed (`act_svc.log` records `issue_id`), webhook payloads, exported issue dumps, or simply by being a low-privilege observer of the attacker\u0027s own workspace whose internals reference foreign issue IDs (cross-workspace links, search across activity events). State: attacker holds `I_T`.\n2. Attacker authenticates and sends `GET /workspaces/W_attacker/issues/I_T/comments`. `require_workspace_member(W_attacker, attacker)` passes (attacker is a member of `W_attacker`). State: control flow enters `list_comments` with `workspace_id=W_attacker, issue_id=I_T`.\n3. `CommentService.list_for_issue(I_T)` runs `SELECT * FROM comments WHERE issue_id = \u0027I_T\u0027` with no workspace constraint. Every comment on the foreign issue is returned: `content` (often the most sensitive part of an issue tracker \u2014 bug-report repro steps with secrets, customer PII, internal triage notes), `author_id`, `author_type`, `parent_id`, `created_at`. State: response body is the full comment thread of the foreign issue.\n4. Attacker repeats with `POST /workspaces/W_attacker/issues/I_T/comments` and a body of `{\"content\": \"\u003cmalicious\u003e\"}`. `CommentService.create(issue_id=I_T, author_id=attacker, ...)` writes a row with the foreign issue\u0027s id and the attacker\u0027s `author_id`. State: a new comment authored by the attacker appears in the foreign workspace\u0027s issue thread, indistinguishable to the foreign workspace\u0027s UI from a legitimate cross-workspace mention. Used at scale this becomes a comment-spam / phishing primitive (links in the comment body) targeting another tenant\u0027s users.\n5. Final state: any attacker with one workspace-member token can exfiltrate every comment in the multi-tenant deployment given the issue UUIDs, and inject arbitrary comments under their own author identity into any foreign issue. The cross-workspace attribution gap is the worst part: the comment is recorded with the attacker\u0027s `author_id`, but the foreign workspace has no member with that id and the foreign workspace\u0027s audit logs show no event (the `act_svc.log` call in `add_comment` is omitted).\n\n## Security Impact\n\n**Severity:** sec-high. CVSS 7.6: network attack, low complexity, low privileges, no user interaction, scope unchanged, high confidentiality (full comment threads), high integrity (cross-workspace comment injection under attacker\u0027s own id), no availability claim.\n**Attacker capability:** read every comment on every issue in the multi-tenant deployment given the issue UUIDs; post arbitrary comments under the attacker\u0027s identity into any foreign issue, allowing comment-spam, phishing-link injection into another tenant\u0027s UI, or social-engineering attribution attacks (the foreign workspace\u0027s UI renders a comment whose author belongs to no member of that workspace).\n**Preconditions:** `praisonai-platform` is deployed multi-tenant; the attacker has any membership token; the target issue\u0027s UUID is known or guessable.\n**Differential:** source-inspection-verified end-to-end. The asymmetry between `CommentService.list_for_issue(issue_id)` (no workspace predicate) and `LabelService.list_for_workspace(workspace_id)` (correctly workspace-scoped) confirms the gap. With the suggested fix below, every comment route first resolves the issue scoped to `workspace_id`, returns 404 if the issue is foreign, and only then proceeds.\n\n## Suggested Fix\n\nResolve the issue scoped to `workspace_id` at the route layer before dispatching to `CommentService`. This both fixes the read and the write paths and avoids changing the `CommentService` signature.\n\n```diff\n--- a/src/praisonai-platform/praisonai_platform/api/routes/issues.py\n+++ b/src/praisonai-platform/praisonai_platform/api/routes/issues.py\n@@ -141,6 +141,11 @@ async def delete_issue(...):\n # \u2500\u2500 Comments \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\n+async def _require_issue_in_workspace(session, workspace_id: str, issue_id: str):\n+ issue = await IssueService(session).get(workspace_id, issue_id) # workspace-scoped get (see companion advisory)\n+ if issue is None:\n+ raise HTTPException(status_code=404, detail=\"Issue not found\")\n+\n @router.post(\"/{issue_id}/comments\", response_model=CommentResponse, status_code=status.HTTP_201_CREATED)\n async def add_comment(\n workspace_id: str,\n@@ -149,6 +154,7 @@ async def add_comment(\n user: AuthIdentity = Depends(require_workspace_member),\n session: AsyncSession = Depends(get_db),\n ):\n+ await _require_issue_in_workspace(session, workspace_id, issue_id)\n svc = CommentService(session)\n comment = await svc.create(\n issue_id=issue_id,\n@@ -167,5 +173,6 @@ async def list_comments(\n user: AuthIdentity = Depends(require_workspace_member),\n session: AsyncSession = Depends(get_db),\n ):\n+ await _require_issue_in_workspace(session, workspace_id, issue_id)\n svc = CommentService(session)\n comments = await svc.list_for_issue(issue_id)\n```\n\nCompanion advisories file the same workspace-scoping gap for `AgentService`, `IssueService`, `ProjectService`, and `LabelService`. Each is a separate exploitable IDOR.",
"id": "GHSA-cp4f-5m9r-5jc2",
"modified": "2026-06-01T14:19:33Z",
"published": "2026-06-01T14:19:33Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-cp4f-5m9r-5jc2"
},
{
"type": "PACKAGE",
"url": "https://github.com/MervinPraison/PraisonAI"
}
],
"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:N",
"type": "CVSS_V3"
}
],
"summary": "praisonai-platform: Comment endpoints accept any issue_id without workspace ownership check, cross-workspace comment read and post IDOR"
}
GHSA-CP88-7FCH-35V3
Vulnerability from github – Published: 2025-05-01 12:31 – Updated: 2025-05-01 12:31The WordPress Simple Shopping Cart plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to, and including, 5.1.3 via the 'process_payment_data' due to missing validation on a user controlled key. This makes it possible for unauthenticated attackers to change the quantity of a product to a negative number, which subtracts the product cost from the total order cost. The attack will only work with Manual Checkout mode, as PayPal and Stripe will not process payments for a negative quantity.
{
"affected": [],
"aliases": [
"CVE-2025-3889"
],
"database_specific": {
"cwe_ids": [
"CWE-639"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-05-01T12:15:17Z",
"severity": "MODERATE"
},
"details": "The WordPress Simple Shopping Cart plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to, and including, 5.1.3 via the \u0027process_payment_data\u0027 due to missing validation on a user controlled key. This makes it possible for unauthenticated attackers to change the quantity of a product to a negative number, which subtracts the product cost from the total order cost. The attack will only work with Manual Checkout mode, as PayPal and Stripe will not process payments for a negative quantity.",
"id": "GHSA-cp88-7fch-35v3",
"modified": "2025-05-01T12:31:16Z",
"published": "2025-05-01T12:31:16Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-3889"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/wordpress-simple-paypal-shopping-cart/tags/5.1.2/wp_shopping_cart.php#L324"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/changeset/3284572"
},
{
"type": "WEB",
"url": "https://www.tipsandtricks-hq.com/ecommerce/simple-shopping-cart-enabling-manual-offline-checkout"
},
{
"type": "WEB",
"url": "https://www.tipsandtricks-hq.com/ecommerce/wp-shopping-cart"
},
{
"type": "WEB",
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/41212533-535e-4a9e-a9b8-1240021a3752?source=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-CPF4-PMR4-W6CX
Vulnerability from github – Published: 2025-11-05 19:52 – Updated: 2025-11-07 21:55Summary
ZITADEL's Organization V2Beta API contains Insecure Direct Object Reference (IDOR) vulnerabilities that allow authenticated users with specific administrator roles within one organization to access and modify data belonging to other organizations.
Impact
ZITADEL's Organization V2Beta API, intended for managing ZITADEL organizations, contains multiple endpoints that fail to properly authorize authenticated users. An attacker with an administrator role for a specific organization could exploit this to bypass access controls and perform unauthorized actions on other organizations within the same ZITADEL instance.
This could allow an attacker to:
- Read organization data, including the name, domains and metadata.
- Manipulate (modify) the corresponding organization data.
- Delete the corresponding data, up to and including the entire organization.
Note that this vulnerability is limited to organization-level data (name, domains, metadata). No other related data (such as users, projects, applications, etc.) is affected.
Affected Versions
Systems running one of the following versions are affected:
- v4.x: 4.0.0-rc.1 through 4.6.2
Patches
The vulnerability has been addressed in the latest release. The patch resolves the issue by correctly validating the caller's permission against the target organization.
- v4.x: Upgrade to version 4.6.3 or later.
Workarounds
Upgrading to a patched version is the recommended solution.
If an immediate upgrade is not possible, mitigation can be achieved by disabling the affected Organization V2Beta API endpoints (e.g., /v2beta/organizations/...) at a reverse proxy or Web Application Firewall (WAF) level.
Questions
If you have any questions or comments about this advisory, please email us at security@zitadel.com
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c 4.6.2"
},
"package": {
"ecosystem": "Go",
"name": "github.com/zitadel/zitadel"
},
"ranges": [
{
"events": [
{
"introduced": "4.0.0-rc.1"
},
{
"fixed": "4.6.3"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/zitadel/zitadel"
},
"ranges": [
{
"events": [
{
"introduced": "1.80.0-v2.20.0.20250414095945-f365cee73242"
},
{
"fixed": "1.80.0-v2.20.0.20251105083648-8dcfff97ed52"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-64431"
],
"database_specific": {
"cwe_ids": [
"CWE-639"
],
"github_reviewed": true,
"github_reviewed_at": "2025-11-05T19:52:01Z",
"nvd_published_at": "2025-11-07T19:16:26Z",
"severity": "HIGH"
},
"details": "### Summary\n\nZITADEL\u0027s Organization V2Beta API contains Insecure Direct Object Reference (IDOR) vulnerabilities that allow authenticated users with specific **administrator** roles within one organization to access and modify data belonging to **other** organizations.\n\n### Impact\n\nZITADEL\u0027s Organization V2Beta API, intended for managing ZITADEL organizations, contains multiple endpoints that fail to properly authorize authenticated users. An attacker with an administrator role for a specific organization could exploit this to bypass access controls and perform unauthorized actions on other organizations within the same ZITADEL instance.\n\nThis could allow an attacker to:\n\n- **Read** organization data, including the name, domains and metadata.\n- **Manipulate** (modify) the corresponding organization data.\n- **Delete** the corresponding data, up to and including the entire organization.\n\nNote that this vulnerability is limited to organization-level data (name, domains, metadata). **No other related data (such as users, projects, applications, etc.) is affected.**\n\n### Affected Versions\n\nSystems running one of the following versions are affected:\n- **v4.x**: `4.0.0-rc.1` through `4.6.2`\n\n### Patches\n\nThe vulnerability has been addressed in the latest release. The patch resolves the issue by correctly validating the caller\u0027s permission against the target organization.\n\n- v4.x: Upgrade to version [4.6.3](https://github.com/zitadel/zitadel/releases/tag/v4.6.3) or later.\n\n### Workarounds\n\nUpgrading to a patched version is the recommended solution.\n\nIf an immediate upgrade is not possible, mitigation can be achieved by disabling the affected Organization V2Beta API endpoints (e.g., /v2beta/organizations/...) at a reverse proxy or Web Application Firewall (WAF) level.\n\n### Questions\n\nIf you have any questions or comments about this advisory, please email us at [security@zitadel.com](mailto:security@zitadel.com)",
"id": "GHSA-cpf4-pmr4-w6cx",
"modified": "2025-11-07T21:55:43Z",
"published": "2025-11-05T19:52:01Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/zitadel/zitadel/security/advisories/GHSA-cpf4-pmr4-w6cx"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-64431"
},
{
"type": "WEB",
"url": "https://github.com/zitadel/zitadel/commit/8dcfff97ed52a8b9fc77ecb1f972744f42cff3ed"
},
{
"type": "PACKAGE",
"url": "https://github.com/zitadel/zitadel"
},
{
"type": "WEB",
"url": "https://github.com/zitadel/zitadel/releases/tag/v4.6.3"
}
],
"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:H/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "IDOR Vulnerabilities in ZITADEL\u0027s Organization API allows Cross-Tenant Data Tempering"
}
GHSA-CPFQ-X7C6-V3CM
Vulnerability from github – Published: 2024-12-05 12:31 – Updated: 2024-12-05 12:31The AnyWhere Elementor plugin for WordPress is vulnerable to Information Exposure in all versions up to, and including, 1.2.11 via the 'INSERT_ELEMENTOR' shortcode due to insufficient restrictions on which posts can be included. This makes it possible for authenticated attackers, with Contributor-level access and above, to extract data from private or draft posts created by Elementor that they should not have access to.
{
"affected": [],
"aliases": [
"CVE-2024-10777"
],
"database_specific": {
"cwe_ids": [
"CWE-639"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-12-05T10:31:38Z",
"severity": "MODERATE"
},
"details": "The AnyWhere Elementor plugin for WordPress is vulnerable to Information Exposure in all versions up to, and including, 1.2.11 via the \u0027INSERT_ELEMENTOR\u0027 shortcode due to insufficient restrictions on which posts can be included. This makes it possible for authenticated attackers, with Contributor-level access and above, to extract data from private or draft posts created by Elementor that they should not have access to.",
"id": "GHSA-cpfq-x7c6-v3cm",
"modified": "2024-12-05T12:31:28Z",
"published": "2024-12-05T12:31:28Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-10777"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/changeset?sfp_email=\u0026sfph_mail=\u0026reponame=\u0026old=3198665%40anywhere-elementor\u0026new=3198665%40anywhere-elementor\u0026sfp_email=\u0026sfph_mail="
},
{
"type": "WEB",
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/c2138634-c149-4fd1-a33d-351bbf633ea3?source=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-CQ3F-VC6P-68FH
Vulnerability from github – Published: 2026-06-04 14:55 – Updated: 2026-06-09 11:58Am I affected?
You are affected if all of the following are true:
- You use
better-authat a version>= 1.6.0, < 1.6.11. - The
deviceAuthorizationplugin is enabled in your auth config (deviceAuthorization()in yourpluginsarray). - A third party can observe a pending user code before the legitimate user completes verification.
The standard device-flow UX displays user codes to humans, so realistic exposure includes shoulder-surfing, screen-share, voice or video calls, support-chat transcripts, referrer headers, and shared logs.
If your application does not enable the deviceAuthorization plugin, you are not affected.
Fix:
- Upgrade to
better-auth@1.6.11or later. - If you cannot upgrade, see workarounds below.
Summary
Better Auth's deviceAuthorization plugin treated any authenticated session as the owner of any pending device code. The ownership gate on POST /device/approve and POST /device/deny short-circuited whenever the row's userId was unset, and the GET /device verification handler did not claim the row. An authenticated attacker who learned a valid user_code before the legitimate user completed approval could bind the polling device to the attacker's account or deny the legitimate flow.
Details
The device authorization flow binds the polling device to the user who entered the user code on the verification page. In affected versions, the plugin only created that binding at approve or deny time, with no claim at the verification step. The ownership check at approve and deny short-circuited when the owner was missing, accepting any authenticated caller instead of rejecting the request.
The fix changes GET /device to claim the pending row for the calling session. The approve and deny gates now require strict equality between the row's owner and the calling session. RFC 8628 §5.5 covers this risk class as Session Spying: a malicious party can hijack a session by completing authorization before the legitimate initiating user does.
Patches
Fixed in better-auth@1.6.11. After the patch, GET /device claims the pending row for the calling session, and POST /device/approve and POST /device/deny reject calls whose session does not match the claimed owner. Custom verification pages must serve GET /device to an authenticated session for the flow to succeed.
Workarounds
If you cannot upgrade immediately:
- Disable the plugin if you do not use the device flow: remove
deviceAuthorization()from yourpluginsarray. - Add a
beforehook onPOST /device/approveandPOST /device/denythat tracks which session calledGET /devicefor each user code, and rejects calls from a different session. - Shorten the pending lifetime of device codes via the
expiresInplugin option to reduce the exploitation window.
Impact
- Account takeover on the polling device: the attacker's session becomes the device's session, so the device operates as the attacker.
- Denial of the legitimate sign-in: the attacker can mark the code as denied, blocking the victim's flow.
Credit
Reported by Quikturn Security Team.
References
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "better-auth"
},
"ranges": [
{
"events": [
{
"introduced": "1.6.0"
},
{
"fixed": "1.6.11"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-45337"
],
"database_specific": {
"cwe_ids": [
"CWE-285",
"CWE-345",
"CWE-639",
"CWE-863"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-04T14:55:52Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Am I affected?\n\nYou are affected if all of the following are true:\n\n- You use `better-auth` at a version `\u003e= 1.6.0, \u003c 1.6.11`.\n- The `deviceAuthorization` plugin is enabled in your auth config (`deviceAuthorization()` in your `plugins` array).\n- A third party can observe a pending user code before the legitimate user completes verification.\n\nThe standard device-flow UX displays user codes to humans, so realistic exposure includes shoulder-surfing, screen-share, voice or video calls, support-chat transcripts, referrer headers, and shared logs.\n\nIf your application does not enable the `deviceAuthorization` plugin, you are not affected.\n\nFix:\n\n1. Upgrade to `better-auth@1.6.11` or later.\n2. If you cannot upgrade, see workarounds below.\n\n### Summary\n\nBetter Auth\u0027s `deviceAuthorization` plugin treated any authenticated session as the owner of any pending device code. The ownership gate on `POST /device/approve` and `POST /device/deny` short-circuited whenever the row\u0027s `userId` was unset, and the `GET /device` verification handler did not claim the row. An authenticated attacker who learned a valid `user_code` before the legitimate user completed approval could bind the polling device to the attacker\u0027s account or deny the legitimate flow.\n\n### Details\n\nThe device authorization flow binds the polling device to the user who entered the user code on the verification page. In affected versions, the plugin only created that binding at approve or deny time, with no claim at the verification step. The ownership check at approve and deny short-circuited when the owner was missing, accepting any authenticated caller instead of rejecting the request.\n\nThe fix changes `GET /device` to claim the pending row for the calling session. The approve and deny gates now require strict equality between the row\u0027s owner and the calling session. RFC 8628 \u00a75.5 covers this risk class as Session Spying: a malicious party can hijack a session by completing authorization before the legitimate initiating user does.\n\n### Patches\n\nFixed in `better-auth@1.6.11`. After the patch, `GET /device` claims the pending row for the calling session, and `POST /device/approve` and `POST /device/deny` reject calls whose session does not match the claimed owner. Custom verification pages must serve `GET /device` to an authenticated session for the flow to succeed.\n\n### Workarounds\n\nIf you cannot upgrade immediately:\n\n- **Disable the plugin** if you do not use the device flow: remove `deviceAuthorization()` from your `plugins` array.\n- **Add a `before` hook** on `POST /device/approve` and `POST /device/deny` that tracks which session called `GET /device` for each user code, and rejects calls from a different session.\n- **Shorten the pending lifetime of device codes** via the `expiresIn` plugin option to reduce the exploitation window.\n\n### Impact\n\n- **Account takeover on the polling device**: the attacker\u0027s session becomes the device\u0027s session, so the device operates as the attacker.\n- **Denial of the legitimate sign-in**: the attacker can mark the code as denied, blocking the victim\u0027s flow.\n\n### Credit\n\nReported by Quikturn Security Team.\n\n### References\n\n- [CWE-285: Improper Authorization](https://cwe.mitre.org/data/definitions/285.html)\n- [CWE-863: Incorrect Authorization](https://cwe.mitre.org/data/definitions/863.html)\n- [CWE-639: Authorization Bypass Through User-Controlled Key](https://cwe.mitre.org/data/definitions/639.html)\n- [RFC 8628 \u00a75.5: Session Spying](https://datatracker.ietf.org/doc/html/rfc8628#section-5.5)",
"id": "GHSA-cq3f-vc6p-68fh",
"modified": "2026-06-09T11:58:19Z",
"published": "2026-06-04T14:55:52Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/better-auth/better-auth/security/advisories/GHSA-cq3f-vc6p-68fh"
},
{
"type": "WEB",
"url": "https://github.com/better-auth/better-auth/pull/9573"
},
{
"type": "PACKAGE",
"url": "https://github.com/better-auth/better-auth"
},
{
"type": "WEB",
"url": "https://github.com/better-auth/better-auth/releases/tag/v1.6.11"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:L",
"type": "CVSS_V3"
}
],
"summary": "Better Auth: Device authorization approve and deny accept any authenticated session while the user code is pending"
}
GHSA-CQ3M-35VG-M37M
Vulnerability from github – Published: 2023-07-06 15:30 – Updated: 2024-04-04 05:26Vulnerability of commands from the modem being intercepted in the atcmdserver module. Attackers may exploit this vulnerability to rewrite the non-volatile random-access memory (NVRAM), or facilitate the exploitation of other vulnerabilities.
{
"affected": [],
"aliases": [
"CVE-2023-37242"
],
"database_specific": {
"cwe_ids": [
"CWE-639"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-07-06T13:15:11Z",
"severity": "CRITICAL"
},
"details": "Vulnerability of commands from the modem being intercepted in the atcmdserver module. Attackers may exploit this vulnerability to rewrite the non-volatile random-access memory (NVRAM), or facilitate the exploitation of other vulnerabilities.",
"id": "GHSA-cq3m-35vg-m37m",
"modified": "2024-04-04T05:26:29Z",
"published": "2023-07-06T15:30:33Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-37242"
},
{
"type": "WEB",
"url": "https://consumer.huawei.com/en/support/bulletin/2023/7"
},
{
"type": "WEB",
"url": "https://device.harmonyos.com/en/docs/security/update/security-bulletins-202307-0000001587168858"
}
],
"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"
}
]
}
GHSA-CQ3Q-PH38-MJWC
Vulnerability from github – Published: 2025-12-18 09:30 – Updated: 2026-01-20 15:32Authorization Bypass Through User-Controlled Key vulnerability in codepeople Contact Form Email contact-form-to-email allows Exploiting Incorrectly Configured Access Control Security Levels.This issue affects Contact Form Email: from n/a through <= 1.3.60.
{
"affected": [],
"aliases": [
"CVE-2025-10019"
],
"database_specific": {
"cwe_ids": [
"CWE-639"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-12-18T08:15:48Z",
"severity": "MODERATE"
},
"details": "Authorization Bypass Through User-Controlled Key vulnerability in codepeople Contact Form Email contact-form-to-email allows Exploiting Incorrectly Configured Access Control Security Levels.This issue affects Contact Form Email: from n/a through \u003c= 1.3.60.",
"id": "GHSA-cq3q-ph38-mjwc",
"modified": "2026-01-20T15:32:18Z",
"published": "2025-12-18T09:30:24Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-10019"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/Wordpress/Plugin/contact-form-to-email/vulnerability/wordpress-contact-form-email-plugin-1-3-59-insecure-direct-object-references-idor-vulnerability?_s_id=cve"
},
{
"type": "WEB",
"url": "https://vdp.patchstack.com/database/Wordpress/Plugin/contact-form-to-email/vulnerability/wordpress-contact-form-email-plugin-1-3-59-insecure-direct-object-references-idor-vulnerability?_s_id=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-CQ47-MVQF-GGFH
Vulnerability from github – Published: 2024-06-30 18:30 – Updated: 2024-06-30 18:30IBM InfoSphere Information Server 11.7 could allow an authenticated user to read or modify sensitive information by bypassing authentication using insecure direct object references. IBM X-Force ID: 288182.
{
"affected": [],
"aliases": [
"CVE-2024-31898"
],
"database_specific": {
"cwe_ids": [
"CWE-639"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-06-30T18:15:03Z",
"severity": "MODERATE"
},
"details": "IBM InfoSphere Information Server 11.7 could allow an authenticated user to read or modify sensitive information by bypassing authentication using insecure direct object references. IBM X-Force ID: 288182.",
"id": "GHSA-cq47-mvqf-ggfh",
"modified": "2024-06-30T18:30:38Z",
"published": "2024-06-30T18:30:38Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-31898"
},
{
"type": "WEB",
"url": "https://exchange.xforce.ibmcloud.com/vulnerabilities/288182"
},
{
"type": "WEB",
"url": "https://www.ibm.com/support/pages/node/7158425"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-CQ9V-9WW6-PHR8
Vulnerability from github – Published: 2026-03-13 21:31 – Updated: 2026-03-13 21:31The GetGenie plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to, and including, 4.3.2 due to missing validation on a user controlled key in the action function. This makes it possible for authenticated attackers, with Author-level access and above, to update post metadata for arbitrary posts. Combined with a lack of input sanitization, this leads to Stored Cross-Site Scripting when a higher-privileged user (such as an Administrator) views the affected post's "Competitor" tab in the GetGenie sidebar.
{
"affected": [],
"aliases": [
"CVE-2026-2257"
],
"database_specific": {
"cwe_ids": [
"CWE-639"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-03-13T19:54:33Z",
"severity": "MODERATE"
},
"details": "The GetGenie plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to, and including, 4.3.2 due to missing validation on a user controlled key in the `action` function. This makes it possible for authenticated attackers, with Author-level access and above, to update post metadata for arbitrary posts. Combined with a lack of input sanitization, this leads to Stored Cross-Site Scripting when a higher-privileged user (such as an Administrator) views the affected post\u0027s \"Competitor\" tab in the GetGenie sidebar.",
"id": "GHSA-cq9v-9ww6-phr8",
"modified": "2026-03-13T21:31:47Z",
"published": "2026-03-13T21:31:46Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-2257"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/getgenie/tags/4.3.2/app/Api/Store.php#L32"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/getgenie/tags/4.3.2/app/Api/Store.php#L74"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/changeset?sfp_email=\u0026sfph_mail=\u0026reponame=\u0026new=3479838%40getgenie%2Ftrunk\u0026old=3446466%40getgenie%2Ftrunk\u0026sfp_email=\u0026sfph_mail="
},
{
"type": "WEB",
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/0f7b119d-ec56-40cb-80ef-67585dadad77?source=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-CQCC-C563-84QX
Vulnerability from github – Published: 2022-05-24 19:17 – Updated: 2024-05-14 21:34In Yellowfin before 9.6.1 it is possible to enumerate and download uploaded images through an Insecure Direct Object Reference vulnerability exploitable by sending a specially crafted HTTP GET request to the page "MIImage.i4".
{
"affected": [],
"aliases": [
"CVE-2021-36389"
],
"database_specific": {
"cwe_ids": [
"CWE-639"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-10-14T19:15:00Z",
"severity": "HIGH"
},
"details": "In Yellowfin before 9.6.1 it is possible to enumerate and download uploaded images through an Insecure Direct Object Reference vulnerability exploitable by sending a specially crafted HTTP GET request to the page \"MIImage.i4\".",
"id": "GHSA-cqcc-c563-84qx",
"modified": "2024-05-14T21:34:39Z",
"published": "2022-05-24T19:17:34Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-36389"
},
{
"type": "WEB",
"url": "https://cyberaz0r.info/2021/10/yellowfin-multiple-vulnerabilities"
},
{
"type": "WEB",
"url": "https://github.com/cyberaz0r/Yellowfin-Multiple-Vulnerabilities/blob/main/README.md"
},
{
"type": "WEB",
"url": "https://wiki.yellowfinbi.com/display/yfcurrent/Release+Notes+for+Yellowfin+9#ReleaseNotesforYellowfin9-Yellowfin9.6"
},
{
"type": "WEB",
"url": "http://packetstormsecurity.com/files/164515/Yellowfin-Cross-Site-Scripting-Insecure-Direct-Object-Reference.html"
},
{
"type": "WEB",
"url": "http://seclists.org/fulldisclosure/2021/Oct/15"
}
],
"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"
}
]
}
Mitigation
For each and every data access, ensure that the user has sufficient privilege to access the record that is being requested.
Mitigation
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
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.