Skip to content

Commit 334e979

Browse files
committed
Code Scanning remmediation, including a cleanup of the VEX docs
Signed-off-by: Erick Bourgeois <erick@jeb.ca>
1 parent 3197843 commit 334e979

29 files changed

Lines changed: 3460 additions & 64 deletions

.github/workflows/build.yaml

Lines changed: 5 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ on:
2929
# Code Scanning, packages:write for GHCR push, attestations:write for
3030
# actions/attest-build-provenance, contents:write for release-asset upload
3131
# — declare them explicitly at job level. See the docker / attest /
32-
# build-vex / semgrep-sast / iac-scan / grype / sign-artifacts /
33-
# slsa-provenance / upload-release-assets jobs below.
32+
# build-vex / iac-scan / grype / sign-artifacts / slsa-provenance /
33+
# upload-release-assets jobs below. (Semgrep SAST runs from sast.yaml.)
3434
permissions:
3535
contents: read
3636

@@ -648,43 +648,9 @@ jobs:
648648
if: github.event_name == 'pull_request'
649649
run: make gitleaks
650650

651-
# ─────────────────────────────────────────────────────────────────────────────
652-
# SAST (Semgrep OSS) — PR + push to main.
653-
# Runs the community Rust / security-audit / secrets / OWASP Top Ten rulesets
654-
# and uploads SARIF to the Code Scanning dashboard. No token required — this
655-
# is the free OSS Community Edition; findings appear under the `semgrep` tool
656-
# category in the Security tab.
657-
# ─────────────────────────────────────────────────────────────────────────────
658-
semgrep-sast:
659-
name: 🔎 SAST (Semgrep)
660-
if: github.event_name != 'release'
661-
runs-on: ubuntu-latest
662-
needs: [verify-commits]
663-
permissions:
664-
contents: read
665-
security-events: write
666-
container:
667-
image: returntocorp/semgrep
668-
steps:
669-
- name: Checkout code
670-
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
671-
672-
- name: Run Semgrep
673-
run: |
674-
semgrep scan \
675-
--config=p/rust \
676-
--config=p/security-audit \
677-
--config=p/secrets \
678-
--config=p/owasp-top-ten \
679-
--sarif --output=semgrep.sarif \
680-
--metrics=off \
681-
--error || true
682-
683-
- name: Upload Semgrep SARIF to Code Scanning
684-
uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
685-
with:
686-
sarif_file: semgrep.sarif
687-
category: semgrep
651+
# Semgrep SAST moved to .github/workflows/sast.yaml so it runs on every
652+
# PR and push with no `paths:` filter (Scorecard's SAST check records
653+
# skipped commits as uncovered otherwise).
688654

689655
# ─────────────────────────────────────────────────────────────────────────────
690656
# IaC security scan (Trivy config) — PR + push to main.

.github/workflows/docs.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,11 @@ jobs:
107107
env:
108108
# Pinned for reproducibility; bump alongside docs/pyproject.toml.
109109
POETRY_VERSION: "1.8.4"
110+
# pip install (vs curl | python3) because the curl-pipe pattern trips
111+
# Scorecard's Pinned-Dependencies downloadThenRun rule; pip uses
112+
# PyPI's per-wheel sha256 from the Python package index.
110113
run: |
111-
curl -sSL https://install.python-poetry.org | python3 - --version "${POETRY_VERSION}"
114+
python3 -m pip install --user "poetry==${POETRY_VERSION}"
112115
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
113116
114117
- name: Configure Poetry

.github/workflows/fuzz.yaml

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Copyright (c) 2025 Erick Bourgeois, firestoned
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
# Short-duration fuzzing of 5-Spot's string parsers on every PR and push.
5+
#
6+
# Each target runs for 60 seconds against libFuzzer via cargo-fuzz. This is a
7+
# credible smoke-fuzz, not continuous fuzzing — the Scorecard FuzzingID check
8+
# only requires that some fuzzing infrastructure exists; follow-up work is
9+
# tracked in ~/dev/roadmaps/5spot-code-scanning-remediation.md § Phase 8 to
10+
# integrate with OSS-Fuzz for continuous coverage.
11+
#
12+
# Requires nightly Rust (libfuzzer-sys uses nightly-only build-script hooks).
13+
14+
name: Fuzz
15+
16+
on:
17+
pull_request:
18+
branches:
19+
- main
20+
paths:
21+
- 'src/**/*.rs'
22+
- 'Cargo.toml'
23+
- 'Cargo.lock'
24+
- 'fuzz/**'
25+
- '.github/workflows/fuzz.yaml'
26+
push:
27+
branches:
28+
- main
29+
paths:
30+
- 'src/**/*.rs'
31+
- 'Cargo.toml'
32+
- 'Cargo.lock'
33+
- 'fuzz/**'
34+
- '.github/workflows/fuzz.yaml'
35+
36+
permissions:
37+
contents: read
38+
39+
jobs:
40+
fuzz:
41+
name: 🎲 Fuzz ${{ matrix.target }}
42+
runs-on: ubuntu-latest
43+
strategy:
44+
fail-fast: false
45+
matrix:
46+
target:
47+
- parse_duration
48+
- parse_day_ranges
49+
- parse_hour_ranges
50+
steps:
51+
- name: Checkout code
52+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
53+
54+
- name: Install nightly Rust toolchain
55+
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable (moving ref — re-pin quarterly)
56+
with:
57+
toolchain: nightly
58+
59+
- name: Install cargo-fuzz
60+
run: cargo install cargo-fuzz --locked
61+
62+
- name: Cache cargo dependencies
63+
uses: firestoned/github-actions/rust/cache-cargo@53b483254bc648903c364ee3c73a546d0936a91e # v1.3.6
64+
65+
- name: Run fuzz target (60 s)
66+
working-directory: fuzz
67+
run: cargo +nightly fuzz run ${{ matrix.target }} -- -max_total_time=60
68+
69+
- name: Upload crash artifacts on failure
70+
if: failure()
71+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
72+
with:
73+
name: fuzz-crash-${{ matrix.target }}
74+
path: fuzz/artifacts/${{ matrix.target }}/
75+
if-no-files-found: ignore

.github/workflows/sast.yaml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Copyright (c) 2025 Erick Bourgeois, firestoned
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
# SAST (Semgrep OSS) — always-on. Runs on every PR and every push to main
5+
# with no `paths:` filter so Scorecard's SAST check records every commit
6+
# as covered (the path-gated Semgrep job in build.yaml was producing
7+
# uncovered-commit events on dependabot and docs-only PRs).
8+
#
9+
# Runs the community Rust / security-audit / secrets / OWASP Top Ten
10+
# rulesets and uploads SARIF to the Code Scanning dashboard under the
11+
# `semgrep` category. No token required — this is the free OSS Community
12+
# Edition.
13+
14+
name: SAST
15+
16+
on:
17+
pull_request:
18+
branches:
19+
- main
20+
push:
21+
branches:
22+
- main
23+
24+
permissions:
25+
contents: read
26+
27+
jobs:
28+
semgrep:
29+
name: 🔎 SAST (Semgrep)
30+
runs-on: ubuntu-latest
31+
permissions:
32+
contents: read
33+
security-events: write
34+
container:
35+
image: returntocorp/semgrep
36+
steps:
37+
- name: Checkout code
38+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
39+
40+
- name: Run Semgrep
41+
run: |
42+
semgrep scan \
43+
--config=p/rust \
44+
--config=p/security-audit \
45+
--config=p/secrets \
46+
--config=p/owasp-top-ten \
47+
--sarif --output=semgrep.sarif \
48+
--metrics=off \
49+
--error || true
50+
51+
- name: Upload Semgrep SARIF to Code Scanning
52+
uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
53+
with:
54+
sarif_file: semgrep.sarif
55+
category: semgrep

.trivyignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,17 @@ AVD-KSV-0012
162162
# with every other capability dropped and the filesystem read-only.
163163
AVD-KSV-0118
164164

165+
# KSV-0116 — DaemonSet 5spot-reclaim-agent should set
166+
# spec.securityContext.runAsGroup, supplementalGroups[*] and fsGroup to
167+
# integer greater than 0. Architecturally required (same root cause as
168+
# KSV-0012 / KSV-0021 / KSV-0105 / KSV-0118). UID 0 is required to read
169+
# /proc/<pid>/{comm,cmdline} under hidepid=2; UID 0 implies GID 0, so
170+
# runAsGroup > 0 cannot be satisfied without abandoning the root
171+
# requirement already justified above. supplementalGroups / fsGroup are
172+
# irrelevant — the agent mounts only host /proc read-only and has no
173+
# writable volumes whose ownership fsGroup would govern.
174+
AVD-KSV-0116
175+
165176
# ─────────────────────────────────────────────────────────────────────────────
166177
# Dockerfile — Dockerfile, Dockerfile.chainguard
167178
# ─────────────────────────────────────────────────────────────────────────────

.vex/CVE-2010-4756.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ cve = "CVE-2010-4756"
77
status = "not_affected"
88
justification = "vulnerable_code_not_in_execute_path"
99
impact_statement = "5-Spot performs no file-system glob expansion; the vulnerable glibc glob() implementation is never called from the controller."
10-
products = ["pkg:oci/5-spot-distroless"]
10+
products = ["pkg:oci/5-spot"]
1111
author = "erick.bourgeois@gmail.com"
1212
timestamp = "2026-04-19T00:00:00Z"

.vex/CVE-2018-20796.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ cve = "CVE-2018-20796"
77
status = "not_affected"
88
justification = "vulnerable_code_not_in_execute_path"
99
impact_statement = "5-Spot uses the Rust regex crate, a separate implementation from glibc's posix/regexec.c; the vulnerable C function is never invoked."
10-
products = ["pkg:oci/5-spot-distroless"]
10+
products = ["pkg:oci/5-spot"]
1111
author = "erick.bourgeois@gmail.com"
1212
timestamp = "2026-04-19T00:00:00Z"

.vex/CVE-2019-1010022.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ cve = "CVE-2019-1010022"
88
status = "not_affected"
99
justification = "vulnerable_code_cannot_be_controlled_by_adversary"
1010
impact_statement = "The controller does not execute adversary-supplied native code; the pre-conditions required to reach the glibc stack-guard bypass do not exist in this workload."
11-
products = ["pkg:oci/5-spot-distroless"]
11+
products = ["pkg:oci/5-spot"]
1212
author = "erick.bourgeois@gmail.com"
1313
timestamp = "2026-04-19T00:00:00Z"

.vex/CVE-2019-1010023.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ cve = "CVE-2019-1010023"
77
status = "not_affected"
88
justification = "vulnerable_code_not_in_execute_path"
99
impact_statement = "The Distroless image ships no ldd or shell; the vulnerable workflow (running ldd on an adversary-supplied ELF) cannot occur at runtime."
10-
products = ["pkg:oci/5-spot-distroless"]
10+
products = ["pkg:oci/5-spot"]
1111
author = "erick.bourgeois@gmail.com"
1212
timestamp = "2026-04-19T00:00:00Z"

.vex/CVE-2019-1010024.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ cve = "CVE-2019-1010024"
77
status = "not_affected"
88
justification = "vulnerable_code_cannot_be_controlled_by_adversary"
99
impact_statement = "An attacker has no primitive within the 5-Spot controller to leak cached stack/heap addresses, so the ASLR-bypass precondition is absent."
10-
products = ["pkg:oci/5-spot-distroless"]
10+
products = ["pkg:oci/5-spot"]
1111
author = "erick.bourgeois@gmail.com"
1212
timestamp = "2026-04-19T00:00:00Z"

0 commit comments

Comments
 (0)