{"id":"CVE-2026-55640","aliases":["GHSA-8vh3-g2qg-2h2c","PYSEC-2026-3866"],"url":"https://o3.security/vulnerability/CVE-2026-55640","summary":"Nextcloud MCP Server: Unauthenticated `POST /webhooks/nextcloud` allows arbitrary vector data deletion when `WEBHOOK_SECRET` is unset ( default )","details":"## Summary\nThe `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.\n\n## Details\n**Vulnerable file:** `nextcloud_mcp_server/vector/webhook_receiver.py`, function `handle_nextcloud_webhook()`, **lines 55-67**\n\n**Root cause 1**: Auth check is guarded by `if secret`: - skipped entirely when `WEBHOOK_SECRET` is unset.\n\n**Root cause 2**: `webhook_secret: str | None = None` in config - no startup validator enforces it, even when vector sync is enabled.\n\n**Trusted field**: `payload[\"user\"][\"uid\"]` in `webhook_parser.py` is used as-is for all Qdrant operations - no cross-check against an authenticated session.\n\n`webhook_receiver.py`, **lines 55-67**:\n```python\nsecret = get_settings().webhook_secret  # None by default\nif secret:                           # skipped entirely when unset\n    ... validate Bearer header ...\nelse:\n    _warn_missing_secret_once()     # just logs, still processes\n```\n`webhook_parser.py`, **line 57**:\n```python\nuser_id = payload[\"user\"][\"uid\"]     # attacker-controlled\n```\n## PoC\n**No credentials required**. Works on any deployment where `WEBHOOK_SECRET` is not explicitly set (the default).\n```json\nPOST /webhooks/nextcloud\nContent-Type: application/json\n\n{\n  \"event\": {\n    \"class\": \"OCP\\\\Files\\\\Events\\\\Node\\\\BeforeNodeDeletedEvent\",\n    \"node\": { \"path\": \"/victim/files/Notes/any.md\", \"id\": 12345 }\n  },\n  \"user\": { \"uid\": \"victim\" },\n  \"time\": 0\n}\n```\n**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.\n\n\n## Impact\n+ Anyone on the network with access to port `8000` - no credentials needed.\n+ Attacker can delete or trigger re-index of any user's vector embeddings in Qdrant by spoofing `user.uid` in the payload.\n+ Mass-sending delete events for all doc IDs destroys the entire semantic search index for all users, requiring a full re-scan to recover.\n\n## Recommend Fix\n1. Enforce `WEBHOOK_SECRET` at startup ( file `config_validators.py` )\n```python\nif vector_sync_enabled and not settings.webhook_secret:\n    raise ConfigurationError(\n        \"WEBHOOK_SECRET must be set when vector sync is enabled\"\n    )\n```\n2. Reject requests when secret is unset ( file `webhook_receiver.py` )\n```python\nsecret = get_settings().webhook_secret\nif not secret:\n    return JSONResponse({\"status\": \"unavailable\"}, status_code=503)\nprovided = request.headers.get(\"authorization\", \"\").encode()\nif not hmac.compare_digest(provided, f\"Bearer {secret}\".encode()):\n    return JSONResponse({\"status\": \"unauthorized\"}, status_code=401)\n```","published":"2026-08-25T16:03:28.085Z","modified":"2026-09-11T03:31:01.500870510Z","cvss":{"score":9.1,"severity":"CRITICAL","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H"},"epss":null,"cisaKev":null,"exploitsKnown":null,"affectedPackages":[{"ecosystem":"PyPI","name":"nextcloud-mcp-server","fixedVersion":"0.117.2"}],"fix":{"url":"https://github.com/cbcoutinho/nextcloud-mcp-server/commit/4fc2b10945108cf1008ec9698291de6706ffcb73","label":"cbcoutinho/nextcloud-mcp-server@4fc2b10"},"references":[{"type":"WEB","url":"https://github.com/cbcoutinho/nextcloud-mcp-server/tree/v0.117.2"},{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/55xxx/CVE-2026-55640.json"},{"type":"ADVISORY","url":"https://github.com/cbcoutinho/nextcloud-mcp-server/security/advisories/GHSA-8vh3-g2qg-2h2c"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-55640"},{"type":"FIX","url":"https://github.com/cbcoutinho/nextcloud-mcp-server/commit/4fc2b10945108cf1008ec9698291de6706ffcb73"},{"type":"PACKAGE","url":"https://github.com/cbcoutinho/nextcloud-mcp-server"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-09-11T03:31:01.500870510Z"}}