Skip to content

Commit 87f1edf

Browse files
committed
deepscan fixes
- validate hashes of manifest command - check non-err non-nil path for redirects in routes - better build security - use local mime.types copy - more hash verification for Docker build, update goreleaser - more guarantees for LFU - improve bonding logic - further confine local FS reads, especially on Windows - deal with range bytes=0-0
1 parent 6a3ff42 commit 87f1edf

10 files changed

Lines changed: 2582 additions & 63 deletions

File tree

.github/workflows/build.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,21 @@ permissions:
1212
jobs:
1313

1414
build:
15-
runs-on: [self-hosted, arm64]
15+
# Fork PRs run attacker-controlled code (both the workflow definition and
16+
# `go test`), so they must never run on the self-hosted runners shared
17+
# with the release pipeline.
18+
runs-on: ubuntu-26.04-arm
19+
permissions:
20+
contents: read
1621
steps:
1722
- name: Harden Runner
1823
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
1924
with:
2025
egress-policy: audit
2126

2227
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
28+
with:
29+
persist-credentials: false
2330

2431
- name: Set up Go
2532
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0

Dockerfile

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@ FROM --platform=$BUILDPLATFORM golang:1-bookworm@sha256:386d475a660466863d9f8c76
22
ARG BUILDARCH TARGETOS TARGETARCH
33
ARG NO_SNAPSHOT=false
44

5-
# Install GoReleaser
6-
RUN wget --no-verbose "https://github.com/goreleaser/goreleaser/releases/download/v2.8.2/goreleaser_2.8.2_$BUILDARCH.deb"
7-
RUN dpkg -i "goreleaser_2.8.2_$BUILDARCH.deb"
5+
# Install GoReleaser, verifying the package against the SHA256 sums published
6+
# in the release's checksums.txt so a swapped release asset fails the build
7+
RUN wget --no-verbose "https://github.com/goreleaser/goreleaser/releases/download/v2.17.0/goreleaser_2.17.0_$BUILDARCH.deb" && \
8+
case "$BUILDARCH" in \
9+
amd64) echo "9dd79854c7e3d87699764fdf5469f111c6d68449943bc83b4f51446e10166996 goreleaser_2.17.0_amd64.deb" | sha256sum -c - ;; \
10+
arm64) echo "5bf732ad34ece73243209525d58a02df546aa2a0e25106631d4058bfd42fad1d goreleaser_2.17.0_arm64.deb" | sha256sum -c - ;; \
11+
*) echo "no pinned goreleaser checksum for build architecture $BUILDARCH" >&2; exit 1 ;; \
12+
esac
13+
RUN dpkg -i "goreleaser_2.17.0_$BUILDARCH.deb"
814

915
# Create and change to the app directory.
1016
WORKDIR /app
@@ -33,7 +39,7 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
3339
# RUN go test ./...
3440

3541
# Produces very small images
36-
FROM gcr.io/distroless/static-debian12 AS packager
42+
FROM gcr.io/distroless/static-debian12@sha256:a9fcaedd4c9b59e12dd65d954f0b5044f19b0647a8a3712e77205df9e7b102cd AS packager
3743

3844
# Extra metadata
3945
LABEL org.opencontainers.image.source="https://github.com/readium/cli"
@@ -43,7 +49,10 @@ LABEL org.opencontainers.image.source="https://github.com/readium/cli"
4349
# this file as part of its mime package, and readium/go-toolkit
4450
# has a mediatype package that falls back to Go's mime
4551
# package to discover a file's mimetype when all else fails.
46-
ADD https://pagure.io/mailcap/raw/master/f/mime.types /etc/
52+
# Vendored into the repository (from https://pagure.io/mailcap)
53+
# so builds are reproducible and don't fetch from a mutable ref.
54+
# ADD https://pagure.io/mailcap/raw/master/f/mime.types /etc/
55+
COPY mime.types /etc/
4756

4857
# Add demo EPUBs to the container by default
4958
# ADD --chown=nonroot:nonroot https://readium-playground-files.storage.googleapis.com/demo/moby-dick.epub /srv/publications/

internal/cli/manifest.go

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,12 @@ Examples:
105105

106106
// Images in directory to ignore for accessibility inference
107107
if inferIgnoreImageDirectoryFlag != "" {
108-
ignoreableImageHashAlgorithms := make([]manifest.HashAlgorithm, len(hash))
109108
if len(hash) == 0 {
110109
return fmt.Errorf("no hash algorithms provided for hashing images in ignored image directory")
111110
}
112-
for i, h := range hash {
113-
ignoreableImageHashAlgorithms[i] = manifest.HashAlgorithm(h)
111+
ignoreableImageHashAlgorithms, err := parseHashAlgorithms(hash)
112+
if err != nil {
113+
return err
114114
}
115115

116116
entries, err := os.ReadDir(inferIgnoreImageDirectoryFlag)
@@ -175,9 +175,9 @@ Examples:
175175
}
176176

177177
if inspectImagesFlag {
178-
hashAlgorithms := make([]manifest.HashAlgorithm, len(hash))
179-
for i, h := range hash {
180-
hashAlgorithms[i] = manifest.HashAlgorithm(h)
178+
hashAlgorithms, err := parseHashAlgorithms(hash)
179+
if err != nil {
180+
return err
181181
}
182182
inspector := &helpers.ImageInspector{
183183
Algorithms: hashAlgorithms,
@@ -206,10 +206,25 @@ Examples:
206206
}
207207

208208
fmt.Println(string(jsonBytes))
209-
return err
209+
return nil
210210
},
211211
}
212212

213+
// Validate algorithms
214+
func parseHashAlgorithms(names []string) ([]manifest.HashAlgorithm, error) {
215+
algorithms := make([]manifest.HashAlgorithm, len(names))
216+
for i, h := range names {
217+
switch a := manifest.HashAlgorithm(strings.ToLower(h)); a {
218+
// Algos accepted by image inspector
219+
case manifest.HashAlgorithmSHA256, manifest.HashAlgorithmMD5, manifest.HashAlgorithmPhashDCT, "https://blurha.sh":
220+
algorithms[i] = a
221+
default:
222+
return nil, fmt.Errorf("unsupported hash algorithm: %s", h)
223+
}
224+
}
225+
return algorithms, nil
226+
}
227+
213228
func init() {
214229
rootCmd.AddCommand(manifestCmd)
215230
manifestCmd.Flags().StringVarP(&indentFlag, "indent", "i", "", "Indentation used to pretty-print")

internal/cli/serve.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"crypto/rand"
66
"encoding/hex"
77
"fmt"
8-
"log"
98
"net/http"
109
"os"
1110
"path/filepath"
@@ -179,7 +178,7 @@ access to publications and prevent abuse or unauthorized access.`,
179178
}
180179
cfg, err := config.LoadDefaultConfig(ctx, options...)
181180
if err != nil {
182-
log.Fatal(err)
181+
return fmt.Errorf("failed loading AWS config: %w", err)
183182
}
184183
_, err = cfg.Credentials.Retrieve(ctx)
185184
if err == nil {

0 commit comments

Comments
 (0)