Files

101 lines
3.5 KiB
Bash

#!/usr/bin/env bash
# Generate the CASA dependency-scan artifacts.
#
# Everything here is read-only against the tree: it runs scanners and writes
# their output into the evidence pack, which lives OUTSIDE this repository.
# This repository is public and the product self-hosts, so a pack naming every
# control's location and every advisory still open is a map for anyone
# attacking an instance that has not updated. CASA_EVIDENCE_DIR overrides the
# destination; the default is ~/warmbly-casa-private/casa/artifacts.
#
# Two artifacts cannot come from this repository and are attached by hand
# before submission: the Qualys SSL Labs report per hostname, and the
# authenticated Burp Suite scan.
#
# A scanner that is not installed is recorded as not run rather than silently
# skipped. An evidence pack with a gap in it is honest; one that hides the gap
# is not.
set -uo pipefail
cd "$(dirname "$0")/.."
OUT="${CASA_EVIDENCE_DIR:-$HOME/warmbly-casa-private/casa/artifacts}"
mkdir -p "$OUT"
case "$(cd "$OUT" && pwd -P)/" in
"$(pwd -P)"/*)
echo "refusing to write the evidence pack inside the repository: $OUT" >&2
echo "this repository is public; set CASA_EVIDENCE_DIR to a path outside it" >&2
exit 1
;;
esac
STAMP="$(date -u '+%Y-%m-%dT%H:%M:%SZ')"
COMMIT="$(git rev-parse HEAD)"
header() {
printf '# %s\n\nGenerated: %s\nCommit: %s\n\n' "$1" "$STAMP" "$COMMIT"
}
echo "==> writing to $OUT"
echo "==> govulncheck (default build)"
{
header "govulncheck, default build"
go run golang.org/x/vuln/cmd/govulncheck@latest ./... 2>&1 || true
} >"$OUT/govulncheck.txt"
echo "==> govulncheck (kafka build)"
{
header "govulncheck, kafka build variant"
printf 'The Avro codec is behind a build tag, so the default scan never compiles it.\n\n'
go run golang.org/x/vuln/cmd/govulncheck@latest -tags kafka ./... 2>&1 || true
} >"$OUT/govulncheck-kafka.txt"
echo "==> pnpm audit per tree"
{
header "Node production dependencies"
for tree in web admin site docs forms; do
printf '\n## %s\n\n```\n' "$tree"
(cd "$tree" && pnpm audit --audit-level=high --prod 2>&1) || true
printf '```\n'
done
} >"$OUT/node-audit.txt"
echo "==> cargo audit"
{
header "Rust dependencies"
if command -v cargo-audit >/dev/null 2>&1; then
(cd tracking && cargo audit 2>&1) || true
else
printf 'cargo-audit is not installed on this machine, so this scan did not run here.\n'
printf 'CI runs it on every dependency change: see the rust job in .github/workflows/security.yml.\n'
fi
} >"$OUT/rust-audit.txt"
echo "==> mix hex.audit"
{
header "Elixir dependencies"
if command -v mix >/dev/null 2>&1 && [ -d realtime/deps ]; then
(cd realtime && mix hex.audit 2>&1) || true
else
printf 'mix is unavailable or dependencies are not fetched, so this scan did not run here.\n'
printf 'Run: cd realtime && mix deps.get && mix hex.audit\n'
fi
} >"$OUT/elixir-audit.txt"
echo "==> trivy"
{
header "Trivy filesystem scan"
if command -v trivy >/dev/null 2>&1; then
trivy fs --scanners vuln --severity HIGH,CRITICAL . 2>&1 || true
else
printf 'trivy is not installed on this machine, so this scan did not run here.\n'
printf 'CI runs it on every dependency change: see the trivy job in .github/workflows/security.yml.\n'
fi
} >"$OUT/trivy.txt"
echo
echo "Wrote:"
ls -1 "$OUT"
echo
echo "Still to attach by hand before submission:"
echo " - Qualys SSL Labs report per hostname, per the pack's scope.md"
echo " - Authenticated Burp Suite scan using the ADA scan configuration"