security: harden CI pipeline against untrusted input (#41, #44, #45)#60
Merged
Merged
Conversation
Closes #41, #44, #45. #41 (Critical) — Actions command/script injection: - Pass derived step outputs (commit_message, error_message, changes) through env: and reference them as quoted shell vars instead of interpolating ${{ }} directly into run: bodies (auto_extract.yml, update_readmes.yml, closing_soon.yml). contribution_approved.yml was already env-hardened in #55. - Validate contributor_email and sanitize host/title in Python before they reach git config / commit messages (contribution_approved.py, auto_extract.py). #44 (Security) — auto_extract.py untrusted input: - Remove the verify=False TLS-bypass fallback (fail closed on SSL errors). - Add SSRF guard: only http(s), resolve host and reject private/loopback/ link-local/reserved ranges, re-check on every redirect hop (safe_get). - Coalesce null model fields ((extracted.get(x) or "")) and use listing.get() in the dedup loop so null/missing fields don't crash the run. - Wrap main() so unexpected errors become a clean util.fail. #45 (Security) — config hardening: - Add permissions: contents: write to update_readmes.yml. - Pin all actions to commit SHAs (checkout v4.3.1, setup-python v5.6.0, github-script v7.1.0) and install Python deps from a pinned requirements.txt. - Escape " and ' in generated markup (util.format_link, generate_gallery.esc). - Pair dangerouslyAllowSVG with a strict CSP + attachment disposition in next.config.ts. Verified: all scripts compile; 17 unit checks pass for the new sanitize/email/ SSRF/escape helpers; all 6 workflows parse; web build succeeds. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jul 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #41, closes #44, closes #45.
First of a stacked series addressing the audit issues (merge bottom-up: this → #43 → #46/#47 → #48 → #51 → #54).
#41 (Critical) — Actions command/script injection
commit_message,error_message,changes) now flow throughenv:and are referenced as quoted shell vars, never interpolated as${{ }}insiderun:bodies —auto_extract.yml,update_readmes.yml,closing_soon.yml. (contribution_approved.ymlwas already env-hardened in fix(ci): repair invalidcontribution_approvedworkflow + harden untrusted inputs #55; this PR only pins its actions.)contributor_emailis validated (strict regex) and host/title are sanitized in Python before reachinggit config/ commit messages.#44 (Security) —
auto_extract.pyuntrusted inputverify=Falsefallback — SSL errors now fail closed.safe_get()allows onlyhttp(s), resolves the host and rejects private/loopback/link-local/reserved IPs, and re-validates on every redirect hop.extracted.get(x) or ""), dedup useslisting.get(), andmain()is wrapped so unexpected errors become a cleanutil.fail.#45 (Security) — config hardening
permissions: contents: writeadded toupdate_readmes.yml.checkoutv4.3.1,setup-pythonv5.6.0,github-scriptv7.1.0); Python deps installed from a pinnedrequirements.txt."/'escaped in generated markup (util.format_link,generate_gallery.esc).dangerouslyAllowSVGpaired with a strict CSP +attachmentdisposition innext.config.ts.Verification
py_compile169.254.169.254, RFC1918,file://all rejected; public https allowed)next buildsucceedsNotes / not included
requests.get/OpenAI (also mentioned in the audit) are handled in the reliability PR ([Medium] Reliability: error-handling & resilience gaps (unguarded parses, no error boundaries, swallowed exceptions) #46), not here.🤖 Generated with Claude Code