Detection Rules
53 rules across 8 attack classes
Each rule maps to a specific attack pattern against GitHub Actions workflows, ordered by severity within each category.
10
17
24
2
Injection
6 rulesShell command injection via expression interpolation in run blocks and reusable workflow inputs.
Attacker-controlled GitHub context expressions interpolated in run: blocks allow arbitrary command injection.
Composite action inputs interpolated directly in run: blocks allow injection when the action is consumed with attacker-controlled values.
workflow_dispatch or repository_dispatch inputs interpolated in run: blocks can be controlled by any user with push access, enabling command injection.
Writing attacker-controllable values to GITHUB_ENV or GITHUB_PATH allows environment variable or PATH manipulation in subsequent steps.
Attacker-controlled values passed as inputs to reusable workflows can cause injection if the called workflow interpolates them unsafely.
Step outputs interpolated in run: blocks may carry attacker-controlled data if a prior step set the output from tainted input.
Triggers
3 rulesDangerous trigger configurations that allow fork-based code execution with elevated privileges.
pull_request_target with actions/checkout referencing the PR head checks out untrusted fork code in a privileged context.
pull_request_target workflow checks out fork code and executes build tools, allowing arbitrary code execution with write permissions.
A workflow_run workflow with write permissions watching a pull_request workflow can be exploited via artifact poisoning for privilege escalation.
Supply Chain
11 rulesUnpinned dependencies, mutable references, and compromised upstream actions.
id-token: write permission with external triggers (pull_request_target, workflow_run, issue_comment) can allow attackers to obtain OIDC tokens and access cloud resources.
Workflow uses a GitHub Action with known security vulnerabilities or that was involved in a supply chain compromise.
Actions pinned to commit SHAs that appear suspicious. Impostor commits can be pushed to a repository via its fork and may not belong to any branch or tag in the original repository.
Third-party actions pinned to mutable tags instead of commit SHAs can be silently replaced with malicious code via tag mutation.
Uses an action reference that is on warden's hardcoded denylist due to a known security incident or EOL status.
A composite or Docker action used by this workflow has unpinned action references inside its own action.yml. SHA-pinning the top-level action does not protect against tag mutation in its internal dependencies, so a compromise of those inner refs still propagates into your workflow.
Detects references to GitHub Actions from known archived or deprecated repositories
Detects actions pinned to a SHA without a version comment, suggesting the pin may be stale or untracked.
Detects actions where the SHA pin comment version disagrees with the version tag in the uses: reference.
Detects actions pinned to branch names (main, master, develop, etc.) that are ambiguous and mutable.
Detects actions known to download external binaries at runtime. SHA-pinning the action does not protect against compromised upstream binaries or install scripts fetched during execution.
Permissions
4 rulesOverly broad permissions, exposed secrets, and insecure credential handling.
Secrets interpolated directly in run: blocks can leak through process listings, shell history, and error messages. Pass them via environment variables instead.
curl or wget commands in run: blocks that also reference secrets may indicate credential exfiltration.
ACTIONS_RUNNER_DEBUG or ACTIONS_STEP_DEBUG is enabled. Debug logging can expose secrets and sensitive information in workflow logs.
A job references secrets (other than GITHUB_TOKEN) without declaring an `environment:`, so no required-reviewers or deployment protection rules gate the secret access.
AI Security
5 rulesAI tool configuration poisoning, MCP config injection, Dependabot security, and trusted publishing best practices.
Privileged-context workflow (pull_request_target, workflow_run, or issue_comment) checks out fork code that may contain poisoned AI assistant configuration. Tracks 30+ verified file paths across Claude Code (CLAUDE.md, .claude/rules/), Cursor (.cursorrules, .cursor/rules/), GitHub Copilot (.github/copilot-instructions.md, .github/instructions/), Aider (.aider.conf.yml, CONVENTIONS.md), Continue (.continue/rules/), Windsurf (.windsurf/rules/), Cline (.clinerules/), Gemini CLI (GEMINI.md, .gemini/), OpenAI Codex CLI (.codex/, AGENTS.md), and the cross-tool AGENTS.md standard.
Privileged-context workflow (pull_request_target, workflow_run, or issue_comment) checks out fork code that may contain malicious Model Context Protocol (MCP) configuration. Tracks 16 verified file paths spanning .mcp.json, mcp_servers.json, .vscode/mcp.json, .cursor/mcp.json, .claude/mcp.json, .claude/mcp_servers.json, claude_desktop_config.json, .continue/mcpServers/, cline_mcp_settings.json and more, enabling detection of tool-server hijacking, secret exfiltration, and silent backdoor injection into AI-generated code.
Detects Dependabot configurations with daily update schedules and no grouping, which can flood PRs
Detects Dependabot-related workflows that may execute untrusted code from pull requests via pull_request_target
Detects PyPI/npm publish workflows using stored API tokens instead of OIDC trusted publishing
Steganography
2 rulesHidden malicious content using Unicode invisible characters and obfuscation patterns.
Invisible Unicode characters detected in workflow file. These can hide malicious commands, alter string comparisons, or use bidirectional text overrides to disguise code.
Suspicious patterns that may indicate malicious activity, including obfuscated payloads, reverse shells, and C2 communication.
Integrity
7 rulesCredential persistence, secret inheritance, insecure commands, and remote script execution.
Detects toJSON(secrets) or secrets.* patterns that expose the entire secrets context, potentially leaking all repository secrets
Detects 'secrets: inherit' in reusable workflow calls, which passes all repository secrets to the called workflow
Detects ACTIONS_ALLOW_UNSECURE_COMMANDS set to true, which re-enables deprecated set-env and add-path workflow commands
Detects hardcoded username or password values in container/services credentials blocks instead of using secrets. Warden checks both username and password fields; some other tools only check password.
Detects curl|bash, wget|sh, and similar patterns that execute remote scripts without verification
Detects actions/checkout without persist-credentials: false when artifacts are uploaded. Below checkout v6, the token is stored in .git/config and leaks via uploaded workspaces. v6+ moved it to $RUNNER_TEMP, which is safer but explicit persist-credentials: false is still the recommended hardening.
Detects container or services image references that are not pinned to a specific @sha256: digest
Logic
15 rulesConditional logic flaws, self-hosted runner exposure, auto-merge bypasses, and cache poisoning.
Detects pull_request triggers combined with self-hosted runners, allowing untrusted PR code to execute on your infrastructure
Detects auto-merge or auto-approve patterns without proper authorization checks
Detects workflow_run triggers that download artifacts without verifying the triggering workflow's conclusion
Workflow uses a risky trigger (pull_request_target, workflow_run, issue_comment, discussion_comment) without an explicit top-level permissions: block, inheriting the repo default which may grant write access.
Detects conditions that are always true: 'if: true', 'if: always()', or self-comparisons like 'github.actor == github.actor'.
Detects contains() checks on user-controlled input used as authorization gates, which can be trivially bypassed.
Detects patterns that bypass GitHub Actions secret redaction: base64 encoding, character splitting, or file write then cat of secrets
Detects actions/cache usage in release or elevated-permission workflows where a poisoned cache could compromise builds
Detects write-all permissions, missing permissions blocks, or unnecessary write grants.
Detects if-conditions checking github.actor against bot names (dependabot[bot], renovate[bot], github-actions[bot]), which can be spoofed by renaming a user account.
Detects permissions entries that lack an explanatory comment
Detects setup actions that may be unnecessary because the tool is already pre-installed on GitHub-hosted runners
Detects base64-encoded strings, hex-encoded strings, or decode operations in non-run contexts (env blocks, with: inputs)
Detects workflows triggered by push or pull_request that lack a concurrency block, which can lead to resource exhaustion
Detects workflow files missing a top-level 'name:' key