Skip to content

Dockerfile: Bun installed via unverified curl | bash while Node base images are SHA256-pinned #74356

@fede-kamel

Description

@fede-kamel

Summary

Dockerfile:47 fetches and executes the Bun installer from https://bun.sh/install with no version pin, checksum, or signature verification:

```dockerfile
if curl --retry 5 --retry-all-errors --retry-delay 2 -fsSL https://bun.sh/install | bash; then
```

This is inconsistent with how every other base image in the same Dockerfile is handled. Lines 15–16 pin both Node images to SHA256 digests:

```dockerfile
ARG OPENCLAW_NODE_BOOKWORM_IMAGE="node:24-bookworm@sha256:3a09aa6354..."
ARG OPENCLAW_NODE_BOOKWORM_SLIM_IMAGE="node:24-bookworm-slim@sha256:e8e2e91b..."
```

Impact

If bun.sh or its CDN is compromised (DNS hijack, CDN takeover, or domain compromise), every Docker image build silently installs and executes attacker-controlled code as root inside the build container. Any CI/CD pipeline rebuilding this image becomes a supply chain vector — the malicious binary ends up in the final runtime image shipped to users.

The retry loop (attempts 1–5) makes this worse: a partial compromise that returns a malicious script on retry 2 would still succeed.

Correct version

.github/actions/setup-node-env/action.yml:50 pins Bun to 1.3.9 via oven-sh/setup-bun@v2.2.0. The Dockerfile should use the same version.

Fix

Replace the curl | bash block with a multi-stage COPY from the official Bun image, keeping the version in sync with CI:

```dockerfile
ARG BUN_VERSION=1.3.9

... other stages ...

FROM ${OPENCLAW_NODE_BOOKWORM_IMAGE} AS build
ARG BUN_VERSION
COPY --from=oven/bun:${BUN_VERSION} /usr/local/bin/bun /usr/local/bin/bun
```

Remove the existing RUN set -eux; for attempt in ... block and the ENV PATH="/root/.bun/bin:${PATH}" line (no longer needed since /usr/local/bin is already on PATH).

For full parity with the Node image pinning strategy, the oven/bun image should also be pinned to a SHA256 digest and updated via Dependabot alongside the Node digests.

Affected file

  • Dockerfile:43–55

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions