Skip to content

Commit 50cbfad

Browse files
committed
security: harden hash-pin script per review, add explicit CodeQL workflow
Sourcery review on #299 flagged two real gaps in the TestPyPI hash-pin step: the wheel glob could silently match >1 file, and the extracted hash wasn't validated before being written into the pin file. Both now fail loudly instead of proceeding on bad input. Also closes Scorecard SAST alert #54: CodeQL was running via GitHub's "default setup", which Scorecard's static SAST check can't see (it only recognizes an explicit codeql-action workflow). Switched to an explicit .github/workflows/codeql.yml (python + actions, matching this repo's actual content) and disabled default setup via the API to avoid the two configurations conflicting. Entire-Checkpoint: 8dc67c1349b0
1 parent 7978203 commit 50cbfad

2 files changed

Lines changed: 65 additions & 1 deletion

File tree

.github/workflows/codeql.yml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: CodeQL
2+
3+
# Explicit workflow (replaces GitHub's "default setup") for two reasons:
4+
# 1. Scorecard's SAST check only recognizes a workflow file running
5+
# github/codeql-action — "default setup" scans just as thoroughly but
6+
# is invisible to that static check (scorecard alert #54).
7+
# 2. Running on `pull_request` (not just a schedule) gates every PR, not
8+
# just periodic scans of main.
9+
10+
on:
11+
push:
12+
branches: ["main"]
13+
pull_request:
14+
branches: ["main"]
15+
schedule:
16+
- cron: "23 8 * * 3"
17+
18+
permissions:
19+
contents: read
20+
21+
jobs:
22+
analyze:
23+
name: Analyze (${{ matrix.language }})
24+
runs-on: ubuntu-latest
25+
permissions:
26+
# Required to upload SARIF results.
27+
security-events: write
28+
# Required to fetch the source.
29+
contents: read
30+
# Required for the "actions" language (workflow analysis).
31+
actions: read
32+
33+
strategy:
34+
fail-fast: false
35+
matrix:
36+
# Matches this repo's actual content — pure Python plus the
37+
# workflow files themselves. (Default setup had also flagged
38+
# c-cpp from autodetection; there's no C/C++ source in the repo,
39+
# only vendored build artifacts under the gitignored .venv/.)
40+
language: ["python", "actions"]
41+
42+
steps:
43+
- name: Checkout repository
44+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
45+
46+
- name: Initialize CodeQL
47+
uses: github/codeql-action/init@e60ea984bd3baa95954f2856bcf24f9eaba46637 # v3
48+
with:
49+
languages: ${{ matrix.language }}
50+
build-mode: none
51+
52+
- name: Perform CodeQL analysis
53+
uses: github/codeql-action/analyze@e60ea984bd3baa95954f2856bcf24f9eaba46637 # v3
54+
with:
55+
category: "/language:${{ matrix.language }}"

.github/workflows/publish.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,17 @@ jobs:
127127
# just dependency confusion.
128128
run: |
129129
VER="${GITHUB_REF_NAME#v}"
130-
WHEEL="$(ls dist/mcpg-"${VER}"-*.whl)"
130+
mapfile -t WHEELS < <(ls dist/mcpg-"${VER}"-*.whl)
131+
if [ "${#WHEELS[@]}" -ne 1 ]; then
132+
echo "::error::Expected exactly one wheel for mcpg==${VER} in dist/, found ${#WHEELS[@]}: ${WHEELS[*]}"
133+
exit 1
134+
fi
135+
WHEEL="${WHEELS[0]}"
131136
HASH="$(python -m pip hash "$WHEEL" | sed -n 's/^--hash=sha256://p')"
137+
if ! [[ "$HASH" =~ ^[0-9a-f]{64}$ ]]; then
138+
echo "::error::pip hash output for $WHEEL did not look like a sha256 hex digest: '${HASH}'"
139+
exit 1
140+
fi
132141
echo "mcpg==${VER} --hash=sha256:${HASH}" > /tmp/mcpg-pin.txt
133142
for i in 1 2 3; do
134143
if python -m pip install --no-deps \

0 commit comments

Comments
 (0)