fix(proxy): exclude reserved path segments from Go container name extraction - #43
Merged
Merged
Conversation
5 tasks done
…raction /containers/<x> is ambiguous: <x> is usually a container name, but Docker also has reserved endpoints at that position — /containers/json lists containers and /containers/create creates one. Rust and TypeScript already excluded create, json and exec; Go did not. The consequence was not just a different verdict. Treating the reserved word as a container name sends the request down the lifecycle branch, where an unknown container falls through to Allow, so Go forwarded DELETE /containers/json to the daemon. Confirmed end to end: before the fix the integration suite gets 404 back from Docker itself, where Rust and TypeScript return 403 without ever forwarding. GET /containers/json is unaffected — with the reserved word excluded it reaches the GET/HEAD passthrough, so listing still works. Adds the same parity tests to all three languages plus three integration cases, as the issue suggested. Verified the tests fail without the fix: the Go unit tests report "create"/"json"/"exec" as container names, and the integration suite reports 404 instead of 403. Closes #24
abienkowski
force-pushed
the
fix/reserved-path-segments
branch
from
October 2, 2026 22:12
68ba311 to
b4dc457
Compare
Collaborator
Author
|
Rebased onto |
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.
Closes #24.
The divergence
/containers/<x>is ambiguous:<x>is usually a container name, but Docker also has reserved endpoints at that position —/containers/jsonlists,/containers/createcreates. Rust (rs/src/proxy.rs:212) and TypeScript (ts/src/proxy.ts:125) already excludedcreate/json/exec. Go excluded nothing:It was worse than the issue described
#24 said Go returned
Allowwhere Rust/TS returnedDeny, and flagged that this was diffed rather than tested. Testing it showed the practical effect is sharper:Allowhere means the request is actually forwarded to the Docker daemon.Reverting the fix and running the integration suite:
That
404comes from Docker, not from the proxy — Go proxied aDELETEthrough to the daemon that Rust and TypeScript refused to forward at all. It happens to be harmless because no container is namedjson, but the request reached the daemon.Path: reserved word taken as a container name → lifecycle branch →
routeByContainerName→ unknown container →ActionAllow.The fix
Go now excludes the same three segments, with a comment pointing at the Rust and TypeScript equivalents so the three stay linked.
GET /containers/jsonis unaffected: with the reserved word excluded it falls through to the GET/HEAD passthrough, so listing still works. That is asserted in all three languages and in the integration suite.Tests
Counts against current
main(05320aa), re-measured after rebasing onto it on 2026-10-02:After the rebase,
make test-allandmake lint-allpass, and all three integration suites (make test-integration{,-rs,-ts}) pass 30/30, including the three new reserved-segment checks. AGENTS.md's Test Coverage section is updated in this PR.The same table of cases is asserted in all three languages, so the parity is now pinned rather than incidental:
DELETE /containers/jsonDELETE /containers/createGET /containers/jsonDELETE /containers/mycontainerGET /containers/mycontainer/jsonVerified the tests fail without the fix — Go unit tests RED on all three reserved words, and the integration suite reports 404 instead of 403.
Verification
make test-all,make lint-all— passmake test-integration{,-rs,-ts}— 30/30 each, identical output across all threeScope note
Docker also has
POST /containers/prune, which none of the three excludes. I checked it rather than assuming: it is consistently denied in all three (POST, no suffix match, falls to default-deny), so there is no parity gap and no behaviour change needed. Left alone deliberately.