Логотип exploitDog
Консоль
Логотип exploitDog

exploitDog

github логотип

GHSA-8vh3-g2qg-2h2c

Опубликовано: 25 авг. 2026
Источник: github
Github: Прошло ревью
CVSS3: 9.1

Описание

nextcloud-mcp-server: Unauthenticated POST /webhooks/nextcloud allows arbitrary vector data deletion when WEBHOOK_SECRET is unset ( default )

Summary

The POST /webhooks/nextcloud endpoint has no authentication by default: WEBHOOK_SECRET defaults to None and is never required by startup validation. When unset, the receiver accepts any unauthenticated POST. The user_id is taken directly from the attacker-supplied payload and passed to Qdrant, allowing an unauthenticated attacker to delete or corrupt vector embeddings for any user.

Details

Vulnerable file: nextcloud_mcp_server/vector/webhook_receiver.py, function handle_nextcloud_webhook(), lines 55-67

Root cause 1: Auth check is guarded by if secret: - skipped entirely when WEBHOOK_SECRET is unset.

Root cause 2: webhook_secret: str | None = None in config - no startup validator enforces it, even when vector sync is enabled.

Trusted field: payload["user"]["uid"] in webhook_parser.py is used as-is for all Qdrant operations - no cross-check against an authenticated session.

webhook_receiver.py, lines 55-67:

secret = get_settings().webhook_secret # None by default if secret: # skipped entirely when unset ... validate Bearer header ... else: _warn_missing_secret_once() # just logs, still processes

webhook_parser.py, line 57:

user_id = payload["user"]["uid"] # attacker-controlled

PoC

No credentials required. Works on any deployment where WEBHOOK_SECRET is not explicitly set (the default).

POST /webhooks/nextcloud Content-Type: application/json { "event": { "class": "OCP\\Files\\Events\\Node\\BeforeNodeDeletedEvent", "node": { "path": "/victim/files/Notes/any.md", "id": 12345 } }, "user": { "uid": "victim" }, "time": 0 }

Result: Qdrant deletes all vector embeddings for victim doc 12345 with no authentication. Attacker can loop over doc IDs for mass deletion. All user targets accepted.

Impact

  • Anyone on the network with access to port 8000 - no credentials needed.
  • Attacker can delete or trigger re-index of any user's vector embeddings in Qdrant by spoofing user.uid in the payload.
  • Mass-sending delete events for all doc IDs destroys the entire semantic search index for all users, requiring a full re-scan to recover.

Recommend Fix

  1. Enforce WEBHOOK_SECRET at startup ( file config_validators.py )
if vector_sync_enabled and not settings.webhook_secret: raise ConfigurationError( "WEBHOOK_SECRET must be set when vector sync is enabled" )
  1. Reject requests when secret is unset ( file webhook_receiver.py )
secret = get_settings().webhook_secret if not secret: return JSONResponse({"status": "unavailable"}, status_code=503) provided = request.headers.get("authorization", "").encode() if not hmac.compare_digest(provided, f"Bearer {secret}".encode()): return JSONResponse({"status": "unauthorized"}, status_code=401)

Пакеты

Наименование

nextcloud-mcp-server

pip
Затронутые версииВерсия исправления

<= 0.117.1

0.117.2

EPSS

Процентиль: 40%
0.00484
Низкий

9.1 Critical

CVSS3

Дефекты

CWE-306

Связанные уязвимости

CVSS3: 9.1
nvd
22 дня назад

Nextcloud MCP Server is a production-ready MCP server that connects AI assistants to a Nextcloud instance. Prior to 0.117.2, the POST /webhooks/nextcloud endpoint in nextcloud_mcp_server/vector/webhook_receiver.py has no authentication by default because WEBHOOK_SECRET defaults to None and startup validation does not require it. When WEBHOOK_SECRET is unset, handle_nextcloud_webhook() accepts unauthenticated requests. The payload["user"]["uid"] field parsed in nextcloud_mcp_server/vector/webhook_parser.py is attacker-controlled and is used without an authenticated-session cross-check for Qdrant operations, allowing a network attacker to delete or trigger re-indexing of vector embeddings for any user and to destroy the semantic search index by sending forged deletion events. This issue is fixed in version 0.117.2.

EPSS

Процентиль: 40%
0.00484
Низкий

9.1 Critical

CVSS3

Дефекты

CWE-306