[security] Managed-Linux --code bootstrap executes the remote code-server installer without integrity verification
Summary
Crabbox's managed-Linux --code capability installs code-server by rendering a root cloud-init bootstrap command that fetches https://code-server.dev/install.sh and pipes the response directly to sh:
curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/usr/local
This capability is opt-in and disabled by default, but it is a documented Crabbox-owned lease capability rather than repository-controlled project automation. When an operator requests --code, Crabbox downloads and installs the code-server runtime as part of the supported managed-Linux Code workflow.
The root security boundary is therefore supply-chain integrity for an external artifact Crabbox downloads and executes during a documented runtime bootstrap. This fits the maintainer policy's in-scope class for "integrity failures in artifacts or images that Crabbox downloads and installs as part of a documented default workflow" and is distinct from out-of-scope hostile repository scripts or a trusted operator intentionally running commands on their own lease.
Affected Components
- Verification target snapshot:
ab1c29f3fd40fad7898a6bf109edd0a17678c937
- Component: managed-Linux cloud-init bootstrap for the Code lease capability
- Affected files:
internal/cli/bootstrap.go:77-107 renders cloud-init runcmd as a root bash -euxo pipefail script and appends optional capability bootstrap commands before marking the lease bootstrapped.
internal/cli/bootstrap.go:1445-1448 appends the cfg.Code install branch, including curl -fsSL https://code-server.dev/install.sh | sh ..., with no digest, signature, or pinned-release verification.
internal/cli/bootstrap_test.go:392-409 asserts that generated cfg.Code cloud-init contains https://code-server.dev/install.sh, confirming this is the current expected generated bootstrap shape.
internal/cli/lease_flags.go:57-60 exposes --code as the lease flag for provisioning or requiring the web code-server capability.
docs/features/capabilities.md:149-165 documents the managed-Linux Code capability and states that the bootstrap installs code-server at /usr/local/bin/code-server.
docs/features/runner-bootstrap.md:72-90 documents --code as an optional lease capability whose readiness check verifies code-server --version.
Attack Path
Attacker role:
An external supply-chain or delivery-path attacker who can control the response served for https://code-server.dev/install.sh at install time. Examples include compromise of the upstream installer endpoint, its hosting/CDN path, DNS/routing for the endpoint, or a TLS-intercepting environment trusted by the lease.
Prerequisites:
- The operator creates or warms a managed Linux lease with
--code.
- The attacker controls the installer script body returned to that lease when cloud-init runs.
- No Crabbox credential, trusted operator account, hostile repository configuration, or access to the operator's local machine is required.
Steps:
- The operator requests a managed Linux lease with
--code.
- Crabbox renders cloud-init for the lease. The generated
runcmd runs as root.
- The
cfg.Code branch installs libatomic1, then runs curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/usr/local with HOME=/root.
- The attacker-controlled installer body executes as root inside the freshly provisioned lease.
- The resulting
/usr/local/bin/code-server runtime is the binary Crabbox later verifies with code-server --version and exposes through the authenticated Code bridge.
Expected result:
Crabbox should either install a reviewed, version-pinned code-server artifact whose digest/signature is verified before execution, or fail closed when the fetched bytes do not match the expected integrity metadata.
Actual result:
The remote installer script is executed as root without a Crabbox-side integrity check. A tampered installer can run arbitrary root commands inside every managed Linux lease provisioned with --code during the attack window.
Impact
A successful attack yields arbitrary root code execution inside the managed Linux lease that requested --code. That code can modify the checked-out project, observe files and command output on the lease, alter the installed code-server runtime, and influence the authenticated Code experience the operator later opens through Crabbox.
The trusted-operator model does not make this expected behavior: the attacker is not a trusted operator, a same-OS-user process, or repository configuration intentionally executed by the operator. The boundary crossed is Crabbox's responsibility for the integrity of external runtime artifacts it downloads and installs in a supported bootstrap path.
The issue is limited to leases that request --code; minimal headless leases and managed Linux leases without the Code capability are unaffected.
Severity Assessment
CVSS Assessment
| Metric |
v3.1 |
v4.0 |
| Score |
7.5 / 10.0 |
7.7 / 10.0 |
| Severity |
High |
High |
| Vector |
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H |
CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:L/SI:L/SA:L |
| Calculator |
CVSS v3.1 Calculator |
CVSS v4.0 Calculator |
The score uses high attack complexity because exploitation requires control of the upstream installer response or its delivery path at the moment a --code lease boots. User interaction is required because an operator must request the Code capability. Privileges required are none for the external attacker, and the impact to the provisioned lease is high for confidentiality, integrity, and availability once the script executes as root.
Recommended Remediation
Replace the remote install-script execution path with a pinned artifact install that fails closed on integrity mismatch.
A minimal fix would:
- Select an explicit code-server version in
internal/cli/bootstrap.go.
- Download a versioned release artifact for the detected architecture, for example from the official GitHub release path.
- Embed reviewed SHA-256 digests for each supported architecture beside the URL/version constants.
- Verify the archive with
sha256sum -c - before extraction or execution.
- Install the verified binary into
/usr/local/bin/code-server.
- Add regression coverage that fails if generated
cfg.Code cloud-init contains code-server.dev/install.sh | sh or lacks the digest verification step.
If a short-term compatibility path must keep the upstream installer script, fetch it to a file first, pin its exact digest, verify that digest before execution, and document the temporary trust model and update process in docs/security.md.
Validation
Validation performed:
- Source review of the current isolated target copy.
- Focused generated-cloud-init test:
GOCACHE=/tmp/crabbox-go-cache GOTMPDIR=/tmp go test ./internal/cli -run TestCloudInitCodeProfile -count=1
Result:
ok github.com/openclaw/crabbox/internal/cli 0.769s
Evidence:
internal/cli/bootstrap.go:77-107 shows the managed Linux bootstrap runs root cloud-init commands under bash -euxo pipefail.
internal/cli/bootstrap.go:1445-1448 shows the cfg.Code branch pipes the remote code-server installer directly into sh.
internal/cli/bootstrap_test.go:392-409 confirms generated cfg.Code cloud-init is expected to contain https://code-server.dev/install.sh and does not install code-server in the base configuration.
internal/cli/bootstrap.go:141-148, :215-216, :278-279, :411-415, and :459-461 show the established Windows bootstrap pattern of verifying downloaded artifacts with SHA-256 before extraction or execution.
internal/cli/bootstrap.go:1642-1659 shows a comparable managed-Linux pinned-install mode for Tailscale that downloads a versioned archive and verifies it with sha256sum -c -.
docs/features/capabilities.md:24-26 states that --code defaults off and must be requested when the lease is created.
docs/features/capabilities.md:149-165 documents the supported Code capability and its /usr/local/bin/code-server install shape.
SECURITY.md:46-48 lists integrity failures in artifacts or images Crabbox downloads and installs as in scope.
Counterevidence considered:
--code is optional and defaults off. This narrows affected leases, but it does not remove the integrity requirement once the operator uses the documented Crabbox-owned capability.
- The attacker must control the external installer response or delivery path. This raises attack complexity, but the resulting root execution is still a supported-boundary crossing because Crabbox executes unverified external bytes during bootstrap.
- The behavior is covered by an existing test, so it is not an accidental dead branch. The test currently preserves the vulnerable install shape rather than proving an integrity check.
[security] Managed-Linux
--codebootstrap executes the remote code-server installer without integrity verificationSummary
Crabbox's managed-Linux
--codecapability installs code-server by rendering a root cloud-init bootstrap command that fetcheshttps://code-server.dev/install.shand pipes the response directly tosh:curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/usr/localThis capability is opt-in and disabled by default, but it is a documented Crabbox-owned lease capability rather than repository-controlled project automation. When an operator requests
--code, Crabbox downloads and installs the code-server runtime as part of the supported managed-Linux Code workflow.The root security boundary is therefore supply-chain integrity for an external artifact Crabbox downloads and executes during a documented runtime bootstrap. This fits the maintainer policy's in-scope class for "integrity failures in artifacts or images that Crabbox downloads and installs as part of a documented default workflow" and is distinct from out-of-scope hostile repository scripts or a trusted operator intentionally running commands on their own lease.
Affected Components
ab1c29f3fd40fad7898a6bf109edd0a17678c937internal/cli/bootstrap.go:77-107renders cloud-initruncmdas a rootbash -euxo pipefailscript and appends optional capability bootstrap commands before marking the lease bootstrapped.internal/cli/bootstrap.go:1445-1448appends thecfg.Codeinstall branch, includingcurl -fsSL https://code-server.dev/install.sh | sh ..., with no digest, signature, or pinned-release verification.internal/cli/bootstrap_test.go:392-409asserts that generatedcfg.Codecloud-init containshttps://code-server.dev/install.sh, confirming this is the current expected generated bootstrap shape.internal/cli/lease_flags.go:57-60exposes--codeas the lease flag for provisioning or requiring the web code-server capability.docs/features/capabilities.md:149-165documents the managed-Linux Code capability and states that the bootstrap installs code-server at/usr/local/bin/code-server.docs/features/runner-bootstrap.md:72-90documents--codeas an optional lease capability whose readiness check verifiescode-server --version.Attack Path
Attacker role:
An external supply-chain or delivery-path attacker who can control the response served for
https://code-server.dev/install.shat install time. Examples include compromise of the upstream installer endpoint, its hosting/CDN path, DNS/routing for the endpoint, or a TLS-intercepting environment trusted by the lease.Prerequisites:
--code.Steps:
--code.runcmdruns as root.cfg.Codebranch installslibatomic1, then runscurl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/usr/localwithHOME=/root./usr/local/bin/code-serverruntime is the binary Crabbox later verifies withcode-server --versionand exposes through the authenticated Code bridge.Expected result:
Crabbox should either install a reviewed, version-pinned code-server artifact whose digest/signature is verified before execution, or fail closed when the fetched bytes do not match the expected integrity metadata.
Actual result:
The remote installer script is executed as root without a Crabbox-side integrity check. A tampered installer can run arbitrary root commands inside every managed Linux lease provisioned with
--codeduring the attack window.Impact
A successful attack yields arbitrary root code execution inside the managed Linux lease that requested
--code. That code can modify the checked-out project, observe files and command output on the lease, alter the installed code-server runtime, and influence the authenticated Code experience the operator later opens through Crabbox.The trusted-operator model does not make this expected behavior: the attacker is not a trusted operator, a same-OS-user process, or repository configuration intentionally executed by the operator. The boundary crossed is Crabbox's responsibility for the integrity of external runtime artifacts it downloads and installs in a supported bootstrap path.
The issue is limited to leases that request
--code; minimal headless leases and managed Linux leases without the Code capability are unaffected.Severity Assessment
CVSS Assessment
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:HCVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:L/SI:L/SA:LThe score uses high attack complexity because exploitation requires control of the upstream installer response or its delivery path at the moment a
--codelease boots. User interaction is required because an operator must request the Code capability. Privileges required are none for the external attacker, and the impact to the provisioned lease is high for confidentiality, integrity, and availability once the script executes as root.Recommended Remediation
Replace the remote install-script execution path with a pinned artifact install that fails closed on integrity mismatch.
A minimal fix would:
internal/cli/bootstrap.go.sha256sum -c -before extraction or execution./usr/local/bin/code-server.cfg.Codecloud-init containscode-server.dev/install.sh | shor lacks the digest verification step.If a short-term compatibility path must keep the upstream installer script, fetch it to a file first, pin its exact digest, verify that digest before execution, and document the temporary trust model and update process in
docs/security.md.Validation
Validation performed:
GOCACHE=/tmp/crabbox-go-cache GOTMPDIR=/tmp go test ./internal/cli -run TestCloudInitCodeProfile -count=1Result:
Evidence:
internal/cli/bootstrap.go:77-107shows the managed Linux bootstrap runs root cloud-init commands underbash -euxo pipefail.internal/cli/bootstrap.go:1445-1448shows thecfg.Codebranch pipes the remote code-server installer directly intosh.internal/cli/bootstrap_test.go:392-409confirms generatedcfg.Codecloud-init is expected to containhttps://code-server.dev/install.shand does not install code-server in the base configuration.internal/cli/bootstrap.go:141-148,:215-216,:278-279,:411-415, and:459-461show the established Windows bootstrap pattern of verifying downloaded artifacts with SHA-256 before extraction or execution.internal/cli/bootstrap.go:1642-1659shows a comparable managed-Linux pinned-install mode for Tailscale that downloads a versioned archive and verifies it withsha256sum -c -.docs/features/capabilities.md:24-26states that--codedefaults off and must be requested when the lease is created.docs/features/capabilities.md:149-165documents the supported Code capability and its/usr/local/bin/code-serverinstall shape.SECURITY.md:46-48lists integrity failures in artifacts or images Crabbox downloads and installs as in scope.Counterevidence considered:
--codeis optional and defaults off. This narrows affected leases, but it does not remove the integrity requirement once the operator uses the documented Crabbox-owned capability.