Skip to content

Commit c7e175a

Browse files
Jonathan D.A. Jewellclaude
andcommitted
fix: repair fix scripts — SPDX license, action SHAs, tmp-paths, CORS
- fix-missing-spdx.sh: AGPL-3.0 → PMPL-1.0-or-later (license policy) - fix-unpinned-actions.sh: updated SHA pins to 2026-02-04 values, scans all workflows instead of single file from finding - fix-tmp-paths.sh: converted from report-only to actual fixer — inserts mktemp block and replaces hardcoded /tmp/ paths - fix-cors-wildcard.sh: removed direct git commit (dispatch runner handles) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e19fc19 commit c7e175a

4 files changed

Lines changed: 100 additions & 59 deletions

File tree

scripts/fix-cors-wildcard.sh

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -62,23 +62,6 @@ if ! diff -q "$FILE" "${FILE}.bak" >/dev/null 2>&1; then
6262
# Add comment explaining the change
6363
sed -i "${LINE}i\\ // SECURITY FIX: Replaced CORS wildcard with environment-based origin" "$FILE"
6464

65-
# Create git commit if in git repo
66-
if [[ -d "$REPO_PATH/.git" ]]; then
67-
cd "$REPO_PATH"
68-
git add "$FILE"
69-
git commit -m "security: replace CORS wildcard with environment variable
70-
71-
Replaced Access-Control-Allow-Origin: '*' with environment-based origin
72-
whitelist to prevent CORS misconfiguration vulnerability (CWE-942).
73-
74-
Set ALLOWED_ORIGINS environment variable to configure permitted origins.
75-
76-
Auto-fixed by: robot-repo-automaton
77-
Finding: $(jq -r '.id' "$FINDING_FILE")
78-
79-
Co-Authored-By: Hypatia Scanner <hypatia@reposystem.dev>"
80-
fi
81-
8265
rm -f "${FILE}.bak"
8366
exit 0
8467
else

scripts/fix-missing-spdx.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ echo "Fixing missing SPDX header in $REPO_PATH..."
1313
FILE_PATH=$(jq -r '.location.file' "$FINDING_FILE")
1414
FULL_PATH="$REPO_PATH/$FILE_PATH"
1515

16-
# Default license (can be overridden by repo's LICENSE file)
17-
DEFAULT_LICENSE="AGPL-3.0-or-later"
16+
# Default license for hyperpolymath repos
17+
DEFAULT_LICENSE="PMPL-1.0-or-later"
1818

1919
if [[ ! -f "$FULL_PATH" ]]; then
2020
echo "ERROR: File not found: $FULL_PATH"

scripts/fix-tmp-paths.sh

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,67 @@ FIXED_COUNT=0
2020

2121
# Find shell files with hardcoded /tmp/ paths
2222
while IFS= read -r -d '' file; do
23-
if grep -q '/tmp/' "$file" 2>/dev/null; then
23+
# Skip binary files
24+
if file "$file" | grep -q "binary"; then
25+
continue
26+
fi
27+
28+
# Only match static /tmp/name patterns (not /tmp/$VAR or /tmp/${VAR})
29+
if grep -qP '/tmp/[a-zA-Z][\w.-]+' "$file" 2>/dev/null; then
2430
rel_path="${file#$REPO_PATH/}"
2531

26-
# Count instances
27-
count=$(grep -c '/tmp/' "$file" 2>/dev/null || echo 0)
32+
# Skip files that already use mktemp properly
33+
if grep -q 'mktemp' "$file" 2>/dev/null; then
34+
echo " SKIP $rel_path — already uses mktemp"
35+
continue
36+
fi
37+
38+
count=$(grep -cP '/tmp/[a-zA-Z][\w.-]+' "$file" 2>/dev/null || echo 0)
39+
40+
# Check if file already has our TMPDIR block (idempotent)
41+
if grep -q 'HYPATIA_TMPDIR' "$file" 2>/dev/null; then
42+
echo " SKIP $rel_path — already patched"
43+
continue
44+
fi
2845

29-
# Replace simple /tmp/filename patterns with variable
30-
# Only do safe replacements (not paths like /tmp/$DYNAMIC)
31-
if grep -qP '/tmp/[a-zA-Z][\w.-]+' "$file" 2>/dev/null; then
32-
# Check if file already uses mktemp
33-
if grep -q 'mktemp' "$file" 2>/dev/null; then
34-
echo " SKIP $rel_path — already uses mktemp ($count /tmp/ refs)"
35-
continue
36-
fi
46+
# Strategy: Add a mktemp block after set -e (or shebang) and replace /tmp/X with $HYPATIA_TMPDIR/X
47+
# Step 1: Extract all static /tmp/filename patterns
48+
tmp_names=$(grep -oP '/tmp/\K[a-zA-Z][\w.-]+' "$file" 2>/dev/null | sort -u)
3749

38-
echo " FOUND $rel_path$count hardcoded /tmp/ path(s)"
39-
((FIXED_COUNT++)) || true
50+
if [[ -z "$tmp_names" ]]; then
51+
continue
4052
fi
53+
54+
# Step 2: Insert mktemp block after the first 'set -' line or after shebang
55+
MKTEMP_BLOCK='# Auto-generated temp dir (replaces hardcoded /tmp/)
56+
HYPATIA_TMPDIR="$(mktemp -d)"
57+
trap '\''rm -rf "$HYPATIA_TMPDIR"'\'' EXIT'
58+
59+
if grep -q '^set -' "$file"; then
60+
# Insert after the 'set -' line
61+
sed -i "/^set -/a\\
62+
\\
63+
${MKTEMP_BLOCK}" "$file" 2>/dev/null || true
64+
else
65+
# Insert after shebang
66+
sed -i "1a\\
67+
\\
68+
${MKTEMP_BLOCK}" "$file" 2>/dev/null || true
69+
fi
70+
71+
# Step 3: Replace /tmp/name with $HYPATIA_TMPDIR/name for each static name
72+
while IFS= read -r name; do
73+
sed -i "s|/tmp/${name}|\"\$HYPATIA_TMPDIR/${name}\"|g" "$file" 2>/dev/null || true
74+
done <<< "$tmp_names"
75+
76+
echo " FIXED $rel_path — replaced $count hardcoded /tmp/ path(s) with mktemp"
77+
((FIXED_COUNT++)) || true
4178
fi
4279
done < <(find "$REPO_PATH" -type f \( -name "*.sh" -o -name "*.bash" \) -not -path "*/\.git/*" -not -path "*/target/*" -print0 2>/dev/null)
4380

4481
echo ""
4582
if [[ "$FIXED_COUNT" -gt 0 ]]; then
46-
echo "Found $FIXED_COUNT file(s) with hardcoded /tmp/ paths (review recommended)"
83+
echo "Fixed $FIXED_COUNT file(s) hardcoded /tmp/ replaced with mktemp"
4784
else
4885
echo "No fixable /tmp/ patterns found"
4986
fi

scripts/fix-unpinned-actions.sh

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,38 +9,59 @@ FINDING_FILE="$2"
99

1010
echo "Fixing unpinned actions in $REPO_PATH..."
1111

12-
# Common action SHA pins (updated 2025-12-15)
12+
# Common action SHA pins (updated 2026-02-04)
1313
declare -A ACTION_PINS=(
14-
["actions/checkout@v4"]="b4ffde65f46336ab88eb53be808477a3936bae11"
15-
["actions/upload-artifact@v4"]="65c79d7f54e76e4e3c7a8f34db0f4ac8b515c478"
16-
["github/codeql-action/init@v3"]="662472033e021d55d94146f66f6058822b0b39fd"
17-
["github/codeql-action/analyze@v3"]="662472033e021d55d94146f66f6058822b0b39fd"
18-
["github/codeql-action/upload-sarif@v3"]="662472033e021d55d94146f66f6058822b0b39fd"
14+
["actions/checkout@v4"]="34e114876b0b11c390a56381ad16ebd13914f8d5"
15+
["actions/checkout@v5"]="93cb6efe18208431cddfb8368fd83d5badbf9bfd"
16+
["github/codeql-action/init@v3"]="6624720a57d4c312633c7b953db2f2da5bcb4c3a"
17+
["github/codeql-action/analyze@v3"]="6624720a57d4c312633c7b953db2f2da5bcb4c3a"
18+
["github/codeql-action/upload-sarif@v3"]="6624720a57d4c312633c7b953db2f2da5bcb4c3a"
1919
["ossf/scorecard-action@v2.4.0"]="62b2cac7ed8198b15735ed49ab1e5cf35480ba46"
20-
["trufflesecurity/trufflehog@v3"]="8a8ef8526528d8a4ff3e2c90be08e25ef8efbd9b"
21-
["editorconfig-checker/action-editorconfig-checker@main"]="9f8f6065f4db902c0c56cafa67cea18b3ebbb680"
20+
["trufflesecurity/trufflehog@main"]="7ee2e0fdffec27d19ccbb8fb3dcf8a83b9d7f9e8"
21+
["editorconfig-checker/action-editorconfig-checker@main"]="4054fa83a075fdf090bd098bdb1c09aaf64a4169"
22+
["dtolnay/rust-toolchain@stable"]="4be9e76fd7c4901c61fb841f559994984270fce7"
23+
["Swatinem/rust-cache@v2"]="779680da715d629ac1d338a641029a2f4372abb5"
24+
["codecov/codecov-action@v5"]="671740ac38dd9b0130fbe1cec585b89eea48d3de"
25+
["slsa-framework/slsa-github-generator@v2.1.0"]="f7dd8c54c2067bafc12ca7a55595d5ee9b75204a"
26+
["webfactory/ssh-agent@v0.9.0"]="dc588b651fe13675774614f8e6a936a468676387"
27+
["ocaml/setup-ocaml@v3"]="dec6499fef64fc5d7ed43d43a87251b7b1c306f5"
28+
["softprops/action-gh-release@v2"]="a06a81a03ee405af7f2048a818ed3f03bbf83c7b"
29+
["actions/configure-pages@v5"]="983d7736d9b0ae728b81ab479565c72886d7745b"
30+
["actions/jekyll-build-pages@v1"]="44a6e6beabd48582f863aeeb6cb2151cc1716697"
31+
["actions/upload-pages-artifact@v3"]="56afc609e74202658d3ffba0e8f6dda462b719fa"
32+
["actions/deploy-pages@v4"]="d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e"
33+
["ruby/setup-ruby@v1"]="09a7688d3b55cf0e976497ff046b70949eeaccfd"
34+
["actions/upload-artifact@v4"]="65c79d7f54e76e4e3c7a8f34db0f4ac8b515c478"
2235
)
2336

24-
# Extract file path from finding
25-
WORKFLOW_FILE=$(jq -r '.location.file' "$FINDING_FILE")
26-
WORKFLOW_PATH="$REPO_PATH/$WORKFLOW_FILE"
37+
# Find all workflow files in repo
38+
FIXED_COUNT=0
39+
while IFS= read -r -d '' workflow; do
40+
rel_path="${workflow#$REPO_PATH/}"
41+
changed=false
2742

28-
if [[ ! -f "$WORKFLOW_PATH" ]]; then
29-
echo "ERROR: Workflow file not found: $WORKFLOW_PATH"
30-
exit 1
31-
fi
43+
for action_version in "${!ACTION_PINS[@]}"; do
44+
SHA="${ACTION_PINS[$action_version]}"
45+
ACTION_NAME="${action_version%@*}"
46+
VERSION="${action_version#*@}"
3247

33-
# Pin actions to SHA
34-
for action_version in "${!ACTION_PINS[@]}"; do
35-
SHA="${ACTION_PINS[$action_version]}"
36-
ACTION_NAME="${action_version%@*}"
37-
VERSION="${action_version#*@}"
48+
# Replace unpinned action with SHA-pinned version
49+
# Match both "uses: action@version" and "uses: action@version # comment"
50+
if grep -q "uses: ${action_version}" "$workflow" 2>/dev/null; then
51+
sed -i "s|uses: ${action_version}|uses: ${ACTION_NAME}@${SHA} # ${VERSION}|g" "$workflow"
52+
echo " Pinned ${ACTION_NAME} (${VERSION}) in ${rel_path}"
53+
changed=true
54+
fi
55+
done
3856

39-
# Replace unpinned action with SHA-pinned version
40-
if grep -q "uses: ${action_version}" "$WORKFLOW_PATH"; then
41-
sed -i "s|uses: ${action_version}|uses: ${ACTION_NAME}@${SHA} # ${VERSION}|g" "$WORKFLOW_PATH"
42-
echo " ✓ Pinned ${ACTION_NAME} to ${SHA}"
57+
if [[ "$changed" == "true" ]]; then
58+
((FIXED_COUNT++)) || true
4359
fi
44-
done
60+
done < <(find "$REPO_PATH/.github/workflows" -type f \( -name "*.yml" -o -name "*.yaml" \) -print0 2>/dev/null)
4561

46-
echo "✅ Unpinned actions fixed in $WORKFLOW_FILE"
62+
echo ""
63+
if [[ "$FIXED_COUNT" -gt 0 ]]; then
64+
echo "Pinned actions in $FIXED_COUNT workflow(s)"
65+
else
66+
echo "No unpinned actions found"
67+
fi

0 commit comments

Comments
 (0)