Improve security of dockerfiles

* Verify checksum of downloaded rust target riscv32imac-unknown-xous_*.zip
* Pin base image to a sha256 digest
* Quote build arg to prevent shell injection attacks
* Run cargo --locked to make sure builds follow Cargo.lock
* Use --proto '=https' for curl to only allow HTTPS protocol to prevent downgrade attacks
* Create non-root user to run cargo commands and build artifacts
This commit is contained in:
Sylvain Bellemare 2026-01-15 17:10:15 +08:00
parent a16c176bab
commit 0959ea80db
No known key found for this signature in database
GPG key ID: C38AE0ECCAB7D5C8
4 changed files with 40 additions and 17 deletions

View file

@ -1,3 +1,5 @@
target/
build/
*.uf2
.direnv
.github
@ -6,3 +8,5 @@
.gitattributes
.gitignore
*.nix
*~
*.swp

View file

@ -11,6 +11,7 @@ on:
env:
REGISTRY: ghcr.io
IMAGE_PREFIX: ${{ github.repository }}
RUST_IMAGE_SHA256: f7a4434bddc5865c07ec0e2804fcde20e9898a2b4c12cac53b22310550a8d6f5
jobs:
build-apps-dabao:
@ -60,6 +61,7 @@ jobs:
type=sha,prefix=sha-
type=raw,value=latest,enable={{is_default_branch}}
- name: Build dabao ${{ matrix.app }} app firmware (uf2 files)
uses: docker/build-push-action@v5
with:
@ -67,6 +69,7 @@ jobs:
file: ./apps-dabao/Dockerfile
build-args: |
app=${{ matrix.app }}
IMG_SHA256=${{ env.RUST_IMAGE_SHA256 }}
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
@ -126,11 +129,14 @@ jobs:
type=sha,prefix=sha-
type=raw,value=latest,enable={{is_default_branch}}
- name: Build bao1x boot1 firmware (uf2 files)
uses: docker/build-push-action@v5
with:
context: .
file: ./bao1x-boot/Dockerfile
build-args: |
IMG_SHA256=${{ env.RUST_IMAGE_SHA256 }}
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

View file

@ -1,5 +1,7 @@
FROM rust:1.92-slim AS toolchain
ARG RUST_VERSION="1.92.0"
ARG IMG_SHA256=""
FROM rust:${RUST_VERSION}-slim-bullseye${IMG_SHA256:+@sha256:${IMG_SHA256}} AS toolchain
ARG EXTRA="1"
RUN set -eux; \
@ -10,19 +12,25 @@ RUN set -eux; \
&& rm -rf /var/lib/apt/lists/* \
&& download_url="https://github.com/betrusted-io/rust/releases/download"; \
zipfile="riscv32imac-unknown-xous_${RUST_VERSION}.zip"; \
curl -L -O "${download_url}/${RUST_VERSION}.${EXTRA}/${zipfile}"; \
curl --proto '=https' --tlsv1.2 -fsSL -O "${download_url}/${RUST_VERSION}.${EXTRA}/${zipfile}"; \
sha256="fc7e7210444ee33c96956c4015eeafe96a588c12d68385ad763a4d1f3c6ec811"; \
echo "${sha256} *${zipfile}" | sha256sum --strict --check -; \
unzip "${zipfile}" -d "$(rustc --print sysroot)"; \
rm "${zipfile}"
RUN rustup target add riscv32imac-unknown-none-elf
FROM toolchain AS builder
ARG app="helloworld"
WORKDIR /usr/src/xous-core
COPY . .
RUN --mount=type=cache,target=/root/.cargo/registry cargo xtask dabao ${app}
RUN useradd --create-home --uid 1000 baozi
USER baozi
WORKDIR /home/baozi/xous-core
COPY --chown=baozi:baozi . .
RUN --mount=type=cache,target=/home/baozi/.cargo/registry,uid=1000,gid=1000 cargo --locked xtask dabao "${app}"
FROM scratch
COPY --from=builder /usr/src/xous-core/target/riscv32imac-unknown-xous-elf/release/apps.uf2 /
COPY --from=builder /usr/src/xous-core/target/riscv32imac-unknown-xous-elf/release/loader.uf2 /
COPY --from=builder /usr/src/xous-core/target/riscv32imac-unknown-xous-elf/release/xous.uf2 /
COPY --from=builder /home/baozi/xous-core/target/riscv32imac-unknown-xous-elf/release/apps.uf2 /
COPY --from=builder /home/baozi/xous-core/target/riscv32imac-unknown-xous-elf/release/loader.uf2 /
COPY --from=builder /home/baozi/xous-core/target/riscv32imac-unknown-xous-elf/release/xous.uf2 /

View file

@ -1,6 +1,7 @@
FROM rust:1.92-slim AS toolchain
ARG RUST_VERSION="1.92.0"
ARG IMG_SHA256=""
FROM rust:${RUST_VERSION}-slim-bullseye${IMG_SHA256:+@sha256:${IMG_SHA256}} AS toolchain
ARG EXTRA="1"
RUN set -eux; \
@ -11,7 +12,9 @@ RUN set -eux; \
&& rm -rf /var/lib/apt/lists/* \
&& download_url="https://github.com/betrusted-io/rust/releases/download"; \
zipfile="riscv32imac-unknown-xous_${RUST_VERSION}.zip"; \
curl -L -O "${download_url}/${RUST_VERSION}.${EXTRA}/${zipfile}"; \
curl --proto '=https' --tlsv1.2 -fsSL -O "${download_url}/${RUST_VERSION}.${EXTRA}/${zipfile}"; \
sha256="fc7e7210444ee33c96956c4015eeafe96a588c12d68385ad763a4d1f3c6ec811"; \
echo "${sha256} *${zipfile}" | sha256sum --strict --check -; \
unzip "${zipfile}" -d "$(rustc --print sysroot)"; \
rm "${zipfile}"
@ -19,12 +22,14 @@ RUN rustup target add riscv32imac-unknown-none-elf
FROM toolchain AS builder
WORKDIR /usr/src/xous-core
COPY . .
RUN --mount=type=cache,target=/root/.cargo/registry cargo xtask bao1x-alt-boot1
RUN --mount=type=cache,target=/root/.cargo/registry cargo xtask bao1x-boot1
RUN useradd --create-home --uid 1000 baozi
USER baozi
WORKDIR /home/baozi/xous-core
COPY --chown=baozi:baozi . .
RUN --mount=type=cache,target=/home/baozi/.cargo/registry,uid=1000,gid=1000 cargo --locked xtask bao1x-alt-boot1
RUN --mount=type=cache,target=/home/baozi/.cargo/registry,uid=1000,gid=1000 cargo --locked xtask bao1x-boot1
FROM scratch
COPY --from=builder /usr/src/xous-core/target/riscv32imac-unknown-none-elf/release/bao1x-boot1.uf2 /
COPY --from=builder /usr/src/xous-core/target/riscv32imac-unknown-none-elf/release/bao1x-alt-boot1.uf2 /
COPY --from=builder /home/baozi/xous-core/target/riscv32imac-unknown-none-elf/release/bao1x-boot1.uf2 /
COPY --from=builder /home/baozi/xous-core/target/riscv32imac-unknown-none-elf/release/bao1x-alt-boot1.uf2 /