fix(security): C18 URL hijacking + C20 unauthenticated workspace deletion - #35
Merged
Merged
Conversation
C18 — Workspace URL hijacking (CRITICAL, CONFIRMED LIVE): POST /registry/register now calls requireWorkspaceToken() before persisting anything. If the workspace has any live auth tokens, the caller must supply a valid Bearer token matching that workspace ID. First registration (no tokens yet) passes through — token is issued at end of this function (unchanged bootstrap contract). Mirrors the same pattern already applied to /registry/heartbeat and /registry/update-card. Attacker POC — overwriting Backend Engineer URL to http://attacker.example.com:9999/steal — now returns 401. C20 — Unauthenticated workspace deletion (CRITICAL, CONFIRMED LIVE): DELETE /workspaces/:id moved from bare router into AdminAuth group. Any valid workspace bearer token grants access (same fail-open bootstrap contract as /settings/secrets). Mass-deletion attack chain (C19 list → C20 delete all) requires auth for the DELETE step. POST /workspaces (create) also moved to AdminAuth to prevent unauthenticated workspace creation. C19 (GET /workspaces topology exposure) deferred — canvas browser has no bearer token; fix requires canvas service-token refactor. Tests: 2 new registry tests — C18 bootstrap (no tokens, passes through and issues token), C18 hijack blocked (has tokens, no bearer → 401). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
HongmingWang-Rabbit
pushed a commit
that referenced
this pull request
Apr 14, 2026
PR #35 gates DELETE /workspaces/:id behind AdminAuth. The E2E smoke test's three DELETE calls (cleanup of echo, summarizer, re-imported bundle) need to send Authorization: Bearer <token>. Any valid live token is accepted — use the token issued to each workspace at /registry/register. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This PR gates DELETE /workspaces/:id behind AdminAuth. The E2E smoke test's three DELETE calls (cleanup of echo, summarizer, re-imported bundle) need to send Authorization: Bearer <token>. Any valid live token is accepted — use the token issued to each workspace at /registry/register. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Contributor
Author
|
Noteworthy: auth — landing after full 7-gate verification.
Merging via merge-commit. |
molecule-ai Bot
pushed a commit
that referenced
this pull request
Apr 21, 2026
fix(security): C18 URL hijacking + C20 unauthenticated workspace deletion
This was referenced Apr 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Threat Summary
Two CRITICAL vulnerabilities confirmed exploited live by Security Auditor (Cycle 8). Zero credentials required. Combined attack chain destroys entire platform in ~10 seconds.
C18 — Workspace URL Hijacking (CRITICAL, CONFIRMED LIVE)
Attack:
POST /registry/registeraccepted re-registration of any workspace ID with no auth. Attacker overwrites any workspace's A2A URL to their server → intercepts all inter-agent messages.Auditor POC:
Fix:
requireWorkspaceToken()called at the top ofRegister()(after SSRF check). Same bootstrap-aware fail-open contract as heartbeat/update-card: if workspace has any live tokens → Bearer required; no tokens → first registration allowed, token issued at end.C20 — Unauthenticated Workspace Deletion (CRITICAL, CONFIRMED LIVE)
Attack:
DELETE /workspaces/:idrequired zero credentials. Combined with unauthenticatedGET /workspaces(C19): enumerate all 12 IDs, delete all → entire platform down.Auditor POC: "deleted two test workspaces with no credentials"
Fix:
DELETE /workspaces/:idandPOST /workspacesmoved intoAdminAuthgroup (same middleware protecting/settings/secrets). Any valid workspace bearer token grants access. Fail-open on fresh install (no global tokens yet).C19 — Topology Exposure via GET /workspaces (deferred)
GET /workspacesreturns all workspace IDs, internal IPs, A2A ports, runtimes, tier, parent IDs without auth. Full fix requires canvas browser to carry a service token — tracked as follow-up. The canvas fetches this endpoint from the browser on every page load; gating it without canvas auth breaks the UI immediately.Tests
TestRegister_C18_BootstrapAllowedNoTokens— first registration (no tokens) → 200 + token issuedTestRegister_C18_HijackBlockedNoBearer— re-registration (has token) without bearer → 401, no DB writeTest plan
cd platform && go test -race ./...— CI will verify (Go not available in Dev Lead container)07bb730confirmed in git logAction still required from host
cd /g/personal_programs/molecule-monorepo git pull origin main docker compose up -d --build platformC2–C17 (PR #31, already merged) remain undeployed for 8 consecutive cycles. This PR adds C18+C20 but deployment is required to activate any fix.
🤖 Generated with Claude Code