Skip to content

Artifact fetch and release accept any session's artifact id #46

@nficano

Description

@nficano

src/Runtime/ArtifactStore.php:40 stamps every stored artifact with a session_key derived from the uploader's session id, but src/Runtime/ArtifactStore.php:66 (fetch()) and src/Runtime/ArtifactStore.php:85 (release()) never compare that key against the requesting session. The dispatcher in src/Internal/Runtime/ArtifactDispatcher.php:50 simply forwards $msg->artifactId to the store without ownership validation. As a result, any authenticated peer that learns or guesses another session's ArtifactId can fetch the bytes — including their declared mediaType and computed sha256 — or release the artifact out from under its owner, all without producing a permission error.

Artifact IDs are ULID-based and not directly guessable, but they leak through subscription fan-out (see the related session-isolation issues), telemetry, and explicit handoff. Once leaked, ARCPRuntime gives the holder full read and delete authority across session boundaries even though the store already knows which session owns each blob.

Fix prompt: Update ArtifactStore::fetch() and ArtifactStore::release() to take the requesting Session (or session id and principal) and reject lookups whose stored session_key does not match. Translate the mismatch into PERMISSION_DENIED at the dispatcher boundary in ArtifactDispatcher::fetch() and ArtifactDispatcher::release(). Add a focused unit test in tests/Integration/ArtifactTest.php that puts an artifact on session A and asserts that session B receives PERMISSION_DENIED when it tries to fetch or release that artifact id.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingseverity:highHigh severity

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions