mirror of
https://github.com/trailofbits/claude-code-devcontainer
synced 2026-06-21 14:11:48 +00:00
Mount .devcontainer/ read-only to prevent container escape on rebuild (#13)
A process inside the container could modify .devcontainer/devcontainer.json to inject malicious mounts or initializeCommand entries that execute on the host during the next rebuild. Bind-mounting .devcontainer/ as read-only blocks this privilege escalation vector. Uses startswith() for the jq filter to be precise and consistent with other mount filters, and documents the SYS_ADMIN guard requirement. Based on PR #12 with review feedback from @dguido addressed. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+2
-1
@@ -46,7 +46,8 @@
|
||||
"source=claude-code-bashhistory-${devcontainerId},target=/commandhistory,type=volume",
|
||||
"source=claude-code-config-${devcontainerId},target=/home/vscode/.claude,type=volume",
|
||||
"source=claude-code-gh-${devcontainerId},target=/home/vscode/.config/gh,type=volume",
|
||||
"source=${localEnv:HOME}/.gitconfig,target=/home/vscode/.gitconfig,type=bind,readonly"
|
||||
"source=${localEnv:HOME}/.gitconfig,target=/home/vscode/.gitconfig,type=bind,readonly",
|
||||
"source=${localWorkspaceFolder}/.devcontainer,target=/workspace/.devcontainer,type=bind,readonly"
|
||||
],
|
||||
"containerEnv": {
|
||||
"NODE_OPTIONS": "--max-old-space-size=4096",
|
||||
|
||||
+9
-1
@@ -82,6 +82,12 @@ get_workspace_folder() {
|
||||
|
||||
# Extract custom mounts from devcontainer.json to a temp file
|
||||
# Returns the temp file path, or empty string if no custom mounts
|
||||
#
|
||||
# Security: .devcontainer/ is mounted read-only inside the container to prevent
|
||||
# a compromised process from injecting malicious mounts or commands into
|
||||
# devcontainer.json that execute on the host during rebuild. This protection
|
||||
# requires that SYS_ADMIN is never added to runArgs (it would allow remounting
|
||||
# read-write).
|
||||
extract_mounts_to_file() {
|
||||
local devcontainer_json="$1"
|
||||
local temp_file
|
||||
@@ -98,7 +104,9 @@ extract_mounts_to_file() {
|
||||
(startswith("source=claude-code-bashhistory-") | not) and
|
||||
(startswith("source=claude-code-config-") | not) and
|
||||
(startswith("source=claude-code-gh-") | not) and
|
||||
(startswith("source=${localEnv:HOME}/.gitconfig,") | not)
|
||||
(startswith("source=${localEnv:HOME}/.gitconfig,") | not) and
|
||||
# Security: read-only .devcontainer mount prevents container escape on rebuild
|
||||
(startswith("source=${localWorkspaceFolder}/.devcontainer,") | not)
|
||||
)
|
||||
) | if length > 0 then . else empty end
|
||||
' "$devcontainer_json" 2>/dev/null) || true
|
||||
|
||||
Reference in New Issue
Block a user