Skip to content

Revert "fix(codeql): go/path-injection in pkg/server/session_manager.go:542" (#3758) - #3788

Merged
trungutt merged 1 commit into
docker:mainfrom
trungutt:revert/3758-workingdir-containment
Jul 22, 2026
Merged

Revert "fix(codeql): go/path-injection in pkg/server/session_manager.go:542" (#3758)#3788
trungutt merged 1 commit into
docker:mainfrom
trungutt:revert/3758-workingdir-containment

Conversation

@trungutt

Copy link
Copy Markdown
Contributor

Why

#3758 added a containment check on user-supplied working_dir in
POST /api/sessions that falls back to os.Getwd() as the permitted
root when --working-dir is unset. That fallback confines every
session to whatever directory the process was launched from, which
breaks all callers that run docker-agent as a long-lived daemon and
legitimately point sessions at arbitrary paths on the host:

working directory "…" is outside the permitted root "…"

--working-dir's documented purpose (cmd/root/flags.go) is a default
cwd for tool execution, not a sandbox root. Overloading it as one made
the API unusable for the majority of deployments.

An earlier attempt at a targeted fix (#3787) made containment opt-in,
but the automated security reviewer kept flagging the "no boundary
when the flag is unset" branch as a regression even though that is the
only behaviour the API can plausibly ship as its default. A clean
revert is simpler: put the code back to its pre-#3758 shape and design
the CodeQL fix separately, on a dedicated containment flag that
defaults to unrestricted.

Follow-up

CodeQL alert #57 is re-opened by this revert. It should be closed by a
new PR that introduces a dedicated --session-workingdir-root (or
similar) flag whose only job is containment, so --working-dir keeps
its documented purpose and hosted / multi-user deployments can opt
into boundary enforcement explicitly.

…go:542" (docker#3758)

docker#3758 added a containment check on user-supplied `working_dir` in
`POST /api/sessions` that falls back to `os.Getwd()` as the permitted
root when `--working-dir` is unset. That fallback confines every
session to whatever directory the process was launched from, which
breaks all callers that run docker-agent as a long-lived daemon and
legitimately point sessions at arbitrary paths on the host:

  working directory "…" is outside the permitted root "…"

`--working-dir`'s documented purpose (`cmd/root/flags.go`) is a
default cwd for tool execution, not a sandbox root. Overloading it as
one made the API unusable for the majority of deployments.

This reverts commit 9194b2b, reversing
changes made to 9650b15. CodeQL alert
docker#57 is re-opened; it should be addressed with a design that does not
overload `--working-dir` as a security boundary — e.g. a dedicated
containment flag whose default is unrestricted.

@docker-agent docker-agent left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assessment: 🟢 APPROVE

This PR is a clean revert of #3758. The surviving + lines pass absWd (the result of filepath.Abs) directly to os.Stat and session.WithWorkingDir, which is the pre-#3758 behaviour. No compile errors, broken imports, nil dereferences, resource leaks, or logic errors were introduced. The removed helper methods (resolveWithinRoot, workingDirRoot) are fully deleted with no dangling call sites, and all imports they used are retained by other code in the file.

@trungutt
trungutt marked this pull request as ready for review July 22, 2026 14:36
@trungutt
trungutt requested a review from a team as a code owner July 22, 2026 14:36

@docker-agent docker-agent left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assessment: 🔴 CRITICAL

This revert re-opens CodeQL path-injection alert #57 (CWE-22). The resolveWithinRoot / workingDirRoot containment methods introduced by #3758 are fully removed; user-supplied working_dir is now accepted without any boundary check.

The PR description acknowledges this and calls for a follow-up --session-workingdir-root flag. Until that follow-up lands, authenticated API callers can direct the agent runtime to operate in any directory on the host filesystem the server process can access.

return nil, errors.New("working directory must be a directory")
}
opts = append(opts, session.WithWorkingDir(resolvedWd))
opts = append(opts, session.WithWorkingDir(absWd))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[HIGH/SECURITY] Path traversal re-introduced: user-supplied working_dir accepted without containment check (CWE-22)

The revert removes the resolveWithinRoot + workingDirRoot helpers that PR #3758 introduced. CreateSession now calls only filepath.Abs(wd) (which resolves relative paths against the process CWD but imposes no root boundary) and os.Stat (existence + directory check only), then stores the result verbatim as the session's WorkingDir.

An authenticated API caller can supply:

  • an absolute path like /etc, /root, or /home/another-user
  • a traversal like ../../../../etc

Both will pass the filepath.Absos.Stat gauntlet. The accepted path is then passed to teamloader.LoadWithConfig(…, teamloader.WithWorkingDir(sess.WorkingDir)) and used throughout the agent runtime, enabling the caller to load arbitrary agent config and access files anywhere the server process can read.

This is the behaviour the PR intentionally restores. CodeQL alert #57 is explicitly re-opened (per PR description). The risk is real: block merging until the companion --session-workingdir-root flag (mentioned in the PR as a follow-up) is in place, or document that the API server is trusted-network-only and the caller is already authenticated.

Confidence Score
🟢 strong 100/100

@trungutt
trungutt merged commit b923ba9 into docker:main Jul 22, 2026
12 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants