diff --git a/.agents/rules/github_actions_workflows.md b/.agents/rules/github_actions_workflows.md index a61f57d4a1..b5c5c77160 100644 --- a/.agents/rules/github_actions_workflows.md +++ b/.agents/rules/github_actions_workflows.md @@ -55,6 +55,36 @@ globs: ".github/workflows/**,.github/actions/**,.github/dependabot.yml" into a single flat directory first (reading paths from the rule's `.txt` manifest) so `/...` subdirectories are not preserved in the artifact. +## Security review +* **No `${{ ... }}` in `run:` or `script:` Blocks**: Never interpolate + `${{ ... }}` expressions (including `${{ secrets.* }}`) directly into `run:` + shell scripts or `actions/github-script` `script:` bodies, even inside + quotes. Bind expressions to `env:` variables (strictly step-scoped for + `secrets.*`) and reference them as quoted shell variables (`"$VAR"`) or + `process.env.VAR`. +* **Untrusted Git Ref Names (`github.head_ref`, `github.ref_name`)**: Treat + branch and tag names as untrusted input. Git ref names allow quotes (`'`, `"`) + and shell metacharacters (`;`, `&`, `|`, `$()`, `` ` ``); reject or guard + against quotes and `#` before writing refs to `.bazelrc`. +* **CLI Argument & Option-Flag Injection**: Validate untrusted inputs (such as + slash-command arguments from issue or PR comments) against strict allowlist + regexes before writing to `$GITHUB_OUTPUT` or passing to tools. Separate + options from positional arguments with `--` when expanding arrays into CLI + commands (e.g. `cmd "${ARGS[@]}" -- "${positional[@]}"`). +* **Authorize Before Mutating State**: In comment- or event-triggered workflows, + verify actor authorization (`author_association` or user allowlist) before + writing to `$GITHUB_OUTPUT` or `$GITHUB_ENV`, posting reactions, or triggering + failure-reporting jobs. +* **Single-Line `$GITHUB_OUTPUT` and `$GITHUB_ENV` Writes**: Reject `\n` and + `\r` in keys and values before writing `key=value` lines to `$GITHUB_OUTPUT` + or `$GITHUB_ENV`. In line-anchored regexes over comment or PR bodies, match + horizontal whitespace (`[ \t]`) and non-linebreak characters (`[^\r\n]`) + rather than `\s` or `.`. +* **Suppress Untrusted Stdout in Privileged Jobs**: Never echo raw PR bodies, + titles, or comment bodies to stdout (pass `--quiet` to `grep`, and use + `printf '%s\n'` instead of `echo`), preventing `::...::` workflow command + injection. + ## Workflow Scripts & Testing * **Separate Script Files (No Inline Scripts)**: Factor non-trivial scripts (such as multi-line shell or Python logic) into standalone files (e.g. `.sh` diff --git a/.agents/skills/review-code/SKILL.md b/.agents/skills/review-code/SKILL.md index 9a35b66904..d5eec4fbd8 100644 --- a/.agents/skills/review-code/SKILL.md +++ b/.agents/skills/review-code/SKILL.md @@ -60,7 +60,9 @@ file from `.agents/skills/review-code/`: - Focus: Audits workflow files (`.github/**`) and workflow tests against `.agents/rules/github_actions_workflows.md` (e.g. `chmod +x` executable permissions, shebangs, action and tool versions, - `./.github/actions/setup-bazel` wrapper usage, fallback jobs). + `./.github/actions/setup-bazel` wrapper usage, fallback jobs, and shell, + script, CLI flag, `$GITHUB_OUTPUT`, or workflow-command injection + vulnerabilities). 8. **`rules_python` Usage Sub-Agent** (`Role: "rules_python Usage Auditor"`): - Prompt file: diff --git a/.agents/skills/review-code/review-workflows-prompt.md b/.agents/skills/review-code/review-workflows-prompt.md index c596ac0a80..0162015458 100644 --- a/.agents/skills/review-code/review-workflows-prompt.md +++ b/.agents/skills/review-code/review-workflows-prompt.md @@ -36,5 +36,21 @@ project's workflow rules and conventions: `uses: ./.github/actions/setup-bazel` (updating `.github/actions/setup-bazel/action.yaml` if new defaults or inputs are needed). +10. Audit for injection and security vulnerabilities: + - Flag any `${{ ... }}` expression interpolated directly inside a `run:` + shell block or `actions/github-script` `script:` body; require binding to + `env:` and referencing via `"$VAR"` or `process.env.VAR`. + - Check how PR author or comment author controlled inputs + (`github.head_ref`, `github.ref_name`, `github.event.pull_request.*`, + `github.event.comment.*`, `github.event.issue.*`, `inputs.*`) flow into + `.bazelrc`, shell commands, and CLI invocations. Require `--` before + positional argument arrays and strict allowlist regex validation on + comment arguments. + - Verify comment and event handlers check actor authorization before writing + to `$GITHUB_OUTPUT` or `$GITHUB_ENV`, reacting to comments, or triggering + failure-reporting jobs. + - Verify helpers writing `key=value` to `$GITHUB_OUTPUT` or `$GITHUB_ENV` + reject `\n` and `\r`, and ensure untrusted PR/comment text is never + echoed to stdout where `::...::` workflow commands could execute. @.agents/skills/review-code/review-report-format.md