Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,16 @@ on:
- cron: '23 4 * * 0'
workflow_dispatch:

# Cancel in-progress runs for the same PR when a new commit lands.
# Cancel in-progress runs for the same commit when a new event lands.
# Key on commit SHA (PR head when triggered by pull_request, pushed SHA
# otherwise) instead of github.ref. With `push: branches: ['**']` and
# `pull_request: branches: [main]` both active, a single PR commit
# triggers two runs — one for the push event (refs/heads/<branch>) and
# one for the PR event (refs/pull/N/merge). Keying on ref leaves both
# in distinct groups, so neither cancels the other. SHA-keyed grouping
# dedups them. Codex round-2 P2 catch on PR #264.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
group: ${{ github.workflow }}-${{ github.event.pull_request.head.sha || github.sha }}
cancel-in-progress: true

permissions:
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/fuzz.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,13 @@ on:
- cron: '17 7 * * 1'
workflow_dispatch:

# Cancel in-progress runs for the same PR when a new commit lands.
# Cancel in-progress runs for the same commit when a new event lands.
# SHA-keyed (PR head SHA or push SHA) instead of ref-keyed, so a single
# PR commit doesn't run twice — once for the push:[**] event and once
# for the pull_request event with different github.ref values. Same
# fix as codeql.yml. Codex round-2 P2 catch on PR #264.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
group: ${{ github.workflow }}-${{ github.event.pull_request.head.sha || github.sha }}
cancel-in-progress: true

permissions:
Expand Down
10 changes: 9 additions & 1 deletion .github/workflows/push.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,15 @@ jobs:
# docs/requirements.txt (generated via `pip-compile --generate-hashes`
# against docs/requirements.in). Closes Scorecard Pinned-Dependencies
# warning on this line.
docker run --rm -v $PWD/docs:/docs -w /docs python:3.9.18 sh -c "pip install --require-hashes -r requirements.txt && PATH=\$PATH:~/.local/bin mkdocs build"
#
# python:3.12-slim, SHA-pinned digest. Required because the
# patched versions of `requests` (>=2.33.0) and `urllib3`
# (>=2.7.0) used to close GHSA-gc5v / -mf9v / -qccp transitive-
# dep advisories declare `requires_python: >=3.10`. Python 3.9
# base would force keeping the vulnerable transitives.
# Digest is multi-platform (OCI image index) — covers amd64
# / arm64 / arm/v5 / arm/v7 / 386 / ppc64le / riscv64 / s390x.
docker run --rm -v $PWD/docs:/docs -w /docs python@sha256:401f6e1a67dad31a1bd78e9ad22d0ee0a3b52154e6bd30e90be696bb6a3d7461 sh -c "pip install --require-hashes -r requirements.txt && PATH=\$PATH:~/.local/bin mkdocs build"
- name: upload docs artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
Expand Down
10 changes: 10 additions & 0 deletions docs/requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,13 @@ mkdocs~=1.5.3
mkdocs-material~=9.4.8
mkdocs-material-extensions~=1.3
mkdocs-mermaid2-plugin~=1.1.1

# Transitive-dep CVE pins surfaced by Scorecard after PR #264:
# - GHSA-gc5v-m9x4-r6x2 (CVE-2026-25645) - requests < 2.33.0 (insecure temp file reuse)
# - GHSA-mf9v-mfxr-j63j (CVE-2026-44432) - urllib3 < 2.7.0 (decompression-bomb bypass)
# - GHSA-qccp-gfcp-xxvc (CVE-2026-44431) - urllib3 < 2.7.0 (cross-origin header leak)
# Pinning the patched floors here forces pip-compile to resolve to safe
# versions. Both deps are reachable through mkdocs-material's plugin
# chain at docs-build time only.
requests>=2.33.0
urllib3>=2.7.0
31 changes: 12 additions & 19 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#
# This file is autogenerated by pip-compile with Python 3.9
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile --allow-unsafe --generate-hashes --output-file=requirements.txt requirements.in
# pip-compile --allow-unsafe --cert=None --client-cert=None --generate-hashes --index-url=None --output-file=requirements.txt --pip-args=None requirements.in
#
babel==2.18.0 \
--hash=sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d \
Expand Down Expand Up @@ -167,12 +167,6 @@ idna==3.15 \
--hash=sha256:048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8 \
--hash=sha256:ca962446ea538f7092a95e057da437618e886f4d349216d2b1e294abfdb65fdc
# via requests
importlib-metadata==8.7.1 \
--hash=sha256:49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb \
--hash=sha256:5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151
# via
# markdown
# mkdocs
jinja2==3.1.6 \
--hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \
--hash=sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67
Expand Down Expand Up @@ -553,10 +547,11 @@ regex==2026.1.15 \
--hash=sha256:fe2fda4110a3d0bc163c2e0664be44657431440722c5c5315c65155cab92f9e5 \
--hash=sha256:febd38857b09867d3ed3f4f1af7d241c5c50362e25ef43034995b77a50df494e
# via mkdocs-material
requests==2.32.5 \
--hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 \
--hash=sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf
requests==2.34.2 \
--hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \
--hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed
# via
# -r requirements.in
# mkdocs-material
# mkdocs-mermaid2-plugin
six==1.17.0 \
Expand All @@ -573,10 +568,12 @@ typing-extensions==4.15.0 \
--hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \
--hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548
# via beautifulsoup4
urllib3==2.6.3 \
--hash=sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed \
--hash=sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4
# via requests
urllib3==2.7.0 \
--hash=sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c \
--hash=sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897
# via
# -r requirements.in
# requests
watchdog==6.0.0 \
--hash=sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a \
--hash=sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2 \
Expand Down Expand Up @@ -609,10 +606,6 @@ watchdog==6.0.0 \
--hash=sha256:e7631a77ffb1f7d2eefa4445ebbee491c720a5661ddf6df3498ebecae5ed375c \
--hash=sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2
# via mkdocs
zipp==3.23.1 \
--hash=sha256:0b3596c50a5c700c9cb40ba8d86d9f2cc4807e9bedb06bcdf7fac85633e444dc \
--hash=sha256:32120e378d32cd9714ad503c1d024619063ec28aad2248dc6672ad13edfa5110
# via importlib-metadata

# The following packages are considered to be unsafe in a requirements file:
setuptools==82.0.1 \
Expand Down
13 changes: 10 additions & 3 deletions pkg/security/cache_fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,21 @@ func FuzzVerifyAndExtract(f *testing.F) {
keyA := CacheKey{Operation: "sbom", ImageDigest: "sha256:A", ConfigHash: "h1"}
keyB := CacheKey{Operation: "scan-grype", ImageDigest: "sha256:B", ConfigHash: "h2"}

future := time.Now().Add(time.Hour)
past := time.Now().Add(-time.Hour)
// Anchor seed timestamps to the SAME fixed clock the fuzz body uses
// (fuzzNow below), not the real wall-clock. Earlier version used
// `time.Now().Add(-time.Hour)` for the "expired" seed, but the fuzz
// body's `now` is fixed to time.Unix(1_700_000_000, 0) (Nov 2023);
// any real-clock "past" is years AFTER that, so the expired-seed
// branch was never exercised by seed #3. Codex round-2 P2 catch.
fuzzNow := time.Unix(1_700_000_000, 0).UTC()
future := fuzzNow.Add(time.Hour)
past := fuzzNow.Add(-time.Hour)

// Seed 1: a known-good signed entry, requested with the matching key.
f.Add(validSignedBytes(f, cache, keyA, []byte("payload-A"), future), "sbom", "sha256:A", "h1")
// Seed 2: same valid bytes, requested with a DIFFERENT key — must miss.
f.Add(validSignedBytes(f, cache, keyA, []byte("payload-A"), future), "scan-grype", "sha256:B", "h2")
// Seed 3: valid entry but already expired — must miss.
// Seed 3: valid entry but already expired vs fuzzNow — must miss.
f.Add(validSignedBytes(f, cache, keyA, []byte("payload-A"), past), "sbom", "sha256:A", "h1")
// Seed 4: a tampered Data payload (MAC no longer matches).
tampered := tamperData(f, cache, keyA, []byte("orig"), []byte("evil"), future)
Expand Down
Loading