mirror of
https://github.com/openclaw/openclaw.git
synced 2026-02-19 18:39:20 -05:00
fix(docker): pin base images to SHA256 digests (#7734)
* fix(docker): pin base images to SHA256 digests for supply chain security Pin all 9 Dockerfiles to immutable SHA256 digests to prevent supply chain attacks where a compromised upstream image could be silently pulled into production builds. Also add Docker ecosystem to Dependabot configuration for automated digest updates. Images pinned: - node:22-bookworm@sha256:cd7bcd2e7a1e6f72052feb023c7f6b722205d3fcab7bbcbd2d1bfdab10b1e935 - node:22-bookworm-slim@sha256:3cfe526ec8dd62013b8843e8e5d4877e297b886e5aace4a59fec25dc20736e45 - debian:bookworm-slim@sha256:98f4b71de414932439ac6ac690d7060df1f27161073c5036a7553723881bffbe - ubuntu:24.04@sha256:cd1dba651b3080c3686ecf4e3c4220f026b521fb76978881737d24f200828b2b Fixes #7731 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * test(docker): add digest pinning regression coverage --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
13
.github/dependabot.yml
vendored
13
.github/dependabot.yml
vendored
@@ -111,3 +111,16 @@ updates:
|
||||
- minor
|
||||
- patch
|
||||
open-pull-requests-limit: 5
|
||||
|
||||
# Docker base images
|
||||
- package-ecosystem: docker
|
||||
directory: /
|
||||
schedule:
|
||||
interval: weekly
|
||||
cooldown:
|
||||
default-days: 7
|
||||
groups:
|
||||
docker-images:
|
||||
patterns:
|
||||
- "*"
|
||||
open-pull-requests-limit: 5
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:22-bookworm
|
||||
FROM node:22-bookworm@sha256:cd7bcd2e7a1e6f72052feb023c7f6b722205d3fcab7bbcbd2d1bfdab10b1e935
|
||||
|
||||
# Install Bun (required for build scripts)
|
||||
RUN curl -fsSL https://bun.sh/install | bash
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM debian:bookworm-slim
|
||||
FROM debian:bookworm-slim@sha256:98f4b71de414932439ac6ac690d7060df1f27161073c5036a7553723881bffbe
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM debian:bookworm-slim
|
||||
FROM debian:bookworm-slim@sha256:98f4b71de414932439ac6ac690d7060df1f27161073c5036a7553723881bffbe
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:22-bookworm-slim
|
||||
FROM node:22-bookworm-slim@sha256:3cfe526ec8dd62013b8843e8e5d4877e297b886e5aace4a59fec25dc20736e45
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:22-bookworm-slim
|
||||
FROM node:22-bookworm-slim@sha256:3cfe526ec8dd62013b8843e8e5d4877e297b886e5aace4a59fec25dc20736e45
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ubuntu:24.04
|
||||
FROM ubuntu:24.04@sha256:cd1dba651b3080c3686ecf4e3c4220f026b521fb76978881737d24f200828b2b
|
||||
|
||||
RUN set -eux; \
|
||||
for attempt in 1 2 3; do \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:22-bookworm-slim
|
||||
FROM node:22-bookworm-slim@sha256:3cfe526ec8dd62013b8843e8e5d4877e297b886e5aace4a59fec25dc20736e45
|
||||
|
||||
RUN set -eux; \
|
||||
for attempt in 1 2 3; do \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:22-bookworm
|
||||
FROM node:22-bookworm@sha256:cd7bcd2e7a1e6f72052feb023c7f6b722205d3fcab7bbcbd2d1bfdab10b1e935
|
||||
|
||||
RUN corepack enable
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:22-bookworm
|
||||
FROM node:22-bookworm@sha256:cd7bcd2e7a1e6f72052feb023c7f6b722205d3fcab7bbcbd2d1bfdab10b1e935
|
||||
|
||||
RUN corepack enable
|
||||
|
||||
|
||||
61
src/docker-image-digests.test.ts
Normal file
61
src/docker-image-digests.test.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { parse } from "yaml";
|
||||
|
||||
const repoRoot = resolve(fileURLToPath(new URL(".", import.meta.url)), "..");
|
||||
|
||||
const DIGEST_PINNED_DOCKERFILES = [
|
||||
"Dockerfile",
|
||||
"Dockerfile.sandbox",
|
||||
"Dockerfile.sandbox-browser",
|
||||
"scripts/docker/cleanup-smoke/Dockerfile",
|
||||
"scripts/docker/install-sh-e2e/Dockerfile",
|
||||
"scripts/docker/install-sh-nonroot/Dockerfile",
|
||||
"scripts/docker/install-sh-smoke/Dockerfile",
|
||||
"scripts/e2e/Dockerfile",
|
||||
"scripts/e2e/Dockerfile.qr-import",
|
||||
] as const;
|
||||
|
||||
type DependabotDockerGroup = {
|
||||
patterns?: string[];
|
||||
};
|
||||
|
||||
type DependabotUpdate = {
|
||||
"package-ecosystem"?: string;
|
||||
directory?: string;
|
||||
schedule?: { interval?: string };
|
||||
groups?: Record<string, DependabotDockerGroup>;
|
||||
};
|
||||
|
||||
type DependabotConfig = {
|
||||
updates?: DependabotUpdate[];
|
||||
};
|
||||
|
||||
describe("docker base image pinning", () => {
|
||||
it("pins selected Dockerfile FROM lines to immutable sha256 digests", async () => {
|
||||
for (const dockerfilePath of DIGEST_PINNED_DOCKERFILES) {
|
||||
const dockerfile = await readFile(resolve(repoRoot, dockerfilePath), "utf8");
|
||||
const fromLine = dockerfile
|
||||
.split(/\r?\n/)
|
||||
.find((line) => line.trimStart().startsWith("FROM "));
|
||||
expect(fromLine, `${dockerfilePath} should define a FROM line`).toBeDefined();
|
||||
expect(fromLine, `${dockerfilePath} FROM must be digest-pinned`).toMatch(
|
||||
/^FROM\s+\S+@sha256:[a-f0-9]{64}$/,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps Dependabot Docker updates enabled for root Dockerfiles", async () => {
|
||||
const raw = await readFile(resolve(repoRoot, ".github/dependabot.yml"), "utf8");
|
||||
const config = parse(raw) as DependabotConfig;
|
||||
const dockerUpdate = config.updates?.find(
|
||||
(update) => update["package-ecosystem"] === "docker" && update.directory === "/",
|
||||
);
|
||||
|
||||
expect(dockerUpdate).toBeDefined();
|
||||
expect(dockerUpdate?.schedule?.interval).toBe("weekly");
|
||||
expect(dockerUpdate?.groups?.["docker-images"]?.patterns).toContain("*");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user