Skip to content

Go router doesn't exclude reserved path segments in extractContainerName (cross-language parity) #24

Description

@abienkowski

Problem

While reviewing the Quint spec's routing table against all three implementations (issue #5), found a cross-language inconsistency in how container names are extracted from the URL path.

Rust (rs/src/proxy.rs) and TypeScript (ts/src/proxy.ts) both explicitly exclude reserved path segments (create, json, exec) from being treated as a container name when parsing /containers/:name/... paths. Go's extractContainerName (go/internal/proxy/router.go) does not.

Concretely: a request like DELETE /containers/json is treated as Allow (unknown-container passthrough) in Go, but falls through to Deny (default-deny) in Rust and TypeScript, because Rust/TS recognize json as a reserved segment rather than a container name.

Impact

Low severity — not exploitable as a privilege escalation on its own (the request would still need to pass all other gates), and not exercised by the Quint model (which doesn't model this specific parsing edge case). But it's a real behavioral difference between the three "equal peer" implementations that could cause confusing/inconsistent behavior depending on which language a deployment uses.

Solution

Update go/internal/proxy/router.go's extractContainerName to exclude the same reserved segments (create, json, exec, and any others Rust/TS already exclude) that Rust and TypeScript already handle, so all three implementations agree on which path segments are container names vs. reserved routing keywords.

Which implementation(s) would this affect?

  • Go

Additional context

Found during the Quint spec review in #5. Confirmed via gh api diff of Router implementations, not by direct testing — recommend adding a unit test case for DELETE /containers/json (and similar) across all three languages once fixed, to catch regressions.

Activity

  1. added
    Type: BugAdded to issues and PRs if they are addressing a bug
    Priority: P3Added to issues and PRs relating to a low severity bugs.
    on Sep 29, 2026
  2. abienkowski commented on Sep 29, 2026

    @abienkowski
    CollaboratorAuthor

    Confirmed directly (the issue notes it was diffed, not tested).

    extractContainerName in Go returns the reserved segment as if it were a container name:

    extractContainerName("/containers/json")   = "json"
    extractContainerName("/containers/create") = "create"
    extractContainerName("/containers/exec")  = "exec"
    

    Rust (rs/src/proxy.rs:212) and TypeScript (ts/src/proxy.ts:125) both exclude create/json/exec, so they return no container name and fall through to default-deny.

    The Go path for DELETE /containers/json is then routeByContainerName("json", "rm"), which for an unknown container returns ActionAllow — so Go allows it where Rust and TypeScript deny it. Matches the reported behaviour.

  3. added 2 commits that reference this issue on Oct 2, 2026
    2cf2085
    b4dc457
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Priority: P3Added to issues and PRs relating to a low severity bugs.Type: BugAdded to issues and PRs if they are addressing a bug

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions