Detection Rules

59 rules across 8 attack classes

Each rule maps to a specific attack pattern against GitHub Actions workflows, ordered by severity within each category.

critical

10

high

19

medium

16

low

7

Filter59 of 59 rules
IDRule & Description

Injection

6 rules

Shell command injection via expression interpolation in run blocks and reusable workflow inputs.

WRD-101
Expression Injectioncritical

Attacker-controlled GitHub context expressions interpolated in run: blocks allow arbitrary command injection.

Related
  • WRD-110Source variant: composite action inputs
  • WRD-111Source variant: dispatch inputs
  • WRD-113Source variant: reusable workflow inputs
  • WRD-130Source variant: tainted step outputs
WRD-110
Composite Action Input Injectionhigh

Composite action inputs interpolated directly in run: blocks allow injection when the action is consumed with attacker-controlled values.

Related
  • WRD-101Family: expression injection (composite action source)
WRD-111
Dispatch Input Injectionhigh

workflow_dispatch or repository_dispatch inputs interpolated in run: blocks can be controlled by any user with push access, enabling command injection.

Related
  • WRD-101Family: expression injection (dispatch input source)
WRD-112
GITHUB_ENV/PATH Write Sinkhigh

Writing attacker-controllable values to GITHUB_ENV or GITHUB_PATH allows environment variable or PATH manipulation in subsequent steps.

WRD-113
Tainted Reusable Workflow Inputshigh

Attacker-controlled values passed as inputs to reusable workflows can cause injection if the called workflow interpolates them unsafely.

Related
  • WRD-101Family: expression injection (reusable workflow source)
WRD-130
Step Output Read (Unknown Provenance)low

Step outputs interpolated in run: blocks may carry attacker-controlled data if a prior step set the output from tainted input.

Related
  • WRD-101Family: expression injection (tainted step output source)

Triggers

3 rules

Dangerous trigger configurations that allow fork-based code execution with elevated privileges.

WRD-201
Dangerous Fork Checkoutcritical

pull_request_target with actions/checkout referencing the PR head checks out untrusted fork code in a privileged context.

WRD-202
Build Tool Execution on Untrusted Codecritical

pull_request_target workflow checks out fork code and executes build tools, allowing arbitrary code execution with write permissions.

WRD-203
Cross-Workflow Privilege Escalationcritical

A workflow_run workflow with write permissions watching a pull_request workflow can be exploited via artifact poisoning for privilege escalation.

Supply Chain

12 rules

Unpinned dependencies, mutable references, and compromised upstream actions.

WRD-301
OIDC Trust Boundary Violationcritical

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.

WRD-302
Known Vulnerable Actioncritical

Workflow uses a GitHub Action with known security vulnerabilities or that was involved in a supply chain compromise.

Related
  • WRD-313Companion: incident-driven hardcoded denylist (this rule is the CVE-database-driven counterpart)
WRD-310
Impostor Commithigh

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.

WRD-313
Denylisted Action Referencehigh

Uses an action reference that is on warden's hardcoded denylist due to a known security incident or EOL status.

Related
  • WRD-302Companion: CVE-database-driven check, this rule is the policy/incident-driven counterpart
WRD-314
Transitive Action Pin Bypasshigh

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.

Related
  • WRD-311Extends: 311 catches unpinned outer uses, 314 descends into pinned composites and flags their unpinned internals
WRD-311
Unpinned Third-Party Actionshigh

Third-party actions pinned to mutable tags instead of commit SHAs can be silently replaced with malicious code via tag mutation.

Severity adjusts:mediumGitHub-owned actions (actions/*, github/*)
Related
  • WRD-324Companion: pinned to ambiguous branch name
  • WRD-313Companion: action is on a known-bad denylist
  • WRD-332Companion: SHA pinned but no version comment
  • WRD-333Companion: SHA pin with mismatched version comment
WRD-324
Branch-Ref Action Pinmedium

Detects actions pinned to branch names (main, master, develop, etc.) that are ambiguous and mutable.

Related
  • WRD-311Family: action pinning hygiene
WRD-331
Archived Action Referencelow

Detects references to GitHub Actions from known archived or deprecated repositories

WRD-332
SHA Pin Missing Version Commentlow

Detects actions pinned to a SHA without a version comment, suggesting the pin may be stale or untracked.

Related
  • WRD-311Family: action pinning hygiene
  • WRD-333Family: SHA pin with mismatched comment
WRD-333
Ref Version Mismatchlow

Detects actions where the SHA pin comment version disagrees with the version tag in the uses: reference.

Related
  • WRD-311Family: action pinning hygiene
  • WRD-332Family: SHA pin missing comment
WRD-335
Unverified Action Creatorlow

Flags uses: steps whose creator is not on warden's allowlist of well-known-safe publishers (GitHub-first-party, major cloud vendors, common language toolchains, vetted OSS). Signal to cross-check and SHA-pin, not evidence of malice.

WRD-345
Runtime Binary Fetchinfo

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. Demoted to Info in v2.0.0: the scanner cannot reliably distinguish a legitimate setup action (setup-go, setup-python) from a compromised one by static analysis, so this rule inventories the risk surface rather than asserting an exploit. A future revision will rework this into an allowlist plus suspicious-behavior split.

Permissions

4 rules

Overly broad permissions, exposed secrets, and insecure credential handling.

WRD-421
Network Call Touches Secretmedium

curl or wget commands in run: blocks that also reference secrets may indicate credential exfiltration.

WRD-422
Step/Runner Debug Enabledmedium

ACTIONS_RUNNER_DEBUG or ACTIONS_STEP_DEBUG is enabled. Debug logging can expose secrets and sensitive information in workflow logs.

WRD-424
Secrets Used Without Environment Gatemedium

A job references secrets (other than GITHUB_TOKEN) without declaring an `environment:`, so no required-reviewers or deployment protection rules gate the secret access.

WRD-440
Secret Reference Inventoryinfo

Inventories where repository secrets are referenced across workflows so reviewers can audit secret reach and exposure.

AI Security

8 rules

AI tool configuration poisoning, MCP config injection, Dependabot security, and trusted publishing best practices.

WRD-510
AI Config Poisoninghigh

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.

Related
  • WRD-511Family: AI tooling supply-chain (MCP server config variant)
WRD-511
MCP Config Injectionhigh

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.

Related
  • WRD-510Family: AI tooling supply-chain (CLAUDE.md / .cursorrules variant)
WRD-522
AI Agent Permission Bypass Flagsmedium

Detects run: blocks that spawn an AI coding-agent CLI (claude, cursor-agent, gemini, codex, aider, continue, cline) with a permission-bypass flag (--dangerously-skip-permissions, --yolo, --trust-all-tools, --full-auto, -y, --unsafe, --no-confirm). Escalates to HIGH on pull_request_target / workflow_run / issue_comment. The exact pivot used by the Nx s1ngularity supply-chain attack in August 2025 to enumerate dev secrets.

WRD-521
Dependabot PR Untrusted Executionmedium

Detects Dependabot-related workflows that may execute untrusted code from pull requests via pull_request_target

WRD-525
Long-Lived Publish Token In Usemedium

Detects PyPI/npm publish workflows using stored API tokens instead of OIDC trusted publishing

WRD-526
GitHub App Token Misusemedium

Detects actions/create-github-app-token calls that skip revocation, leave repositories unspecified, or leave permissions unspecified

WRD-527
Registry Publish Without Trusted Publishingmedium

Complements WRD-525 (PyPI/npm) by flagging long-lived Cargo (CARGO_REGISTRY_TOKEN) and RubyGems (GEM_HOST_API_KEY) publish tokens. Both registries now support OIDC trusted publishing.

WRD-540
Dependabot Daily Without Groupinginfo

Detects Dependabot configurations with daily update schedules and no grouping, which can flood PRs

Steganography

2 rules

Hidden malicious content using Unicode invisible characters and obfuscation patterns.

WRD-602
Workflow Embedded IOCcritical

Suspicious patterns that may indicate malicious activity, including obfuscated payloads, reverse shells, and C2 communication.

WRD-621
Suspicious Invisible Unicodemedium

Invisible Unicode characters detected in workflow file. These can hide malicious commands, alter string comparisons, or use bidirectional text overrides to disguise code.

Integrity

8 rules

Credential persistence, secret inheritance, insecure commands, and remote script execution.

WRD-701
toJSON(secrets) Exposurecritical

Detects toJSON(secrets) or secrets.* patterns that expose the entire secrets context, potentially leaking all repository secrets

WRD-712
Insecure Commands Allowedhigh

Detects ACTIONS_ALLOW_UNSECURE_COMMANDS set to true, which re-enables deprecated set-env and add-path workflow commands

WRD-714
Curl Pipe Bashhigh

Detects curl|bash, wget|sh, and similar patterns that execute remote scripts without verification

WRD-715
Debug Artifact Env Exposurehigh

Detects ACTIONS_STEP_DEBUG / ACTIONS_RUNNER_DEBUG enabled in the same job as actions/upload-artifact. The debug dump includes every runner env var (GITHUB_TOKEN included), so anyone with repo read can download the artifact and extract a live token. CodeQLEAKED pattern, CVE-2025-24362.

WRD-721
Reusable Workflow Secrets Inheritmedium

Detects 'secrets: inherit' in reusable workflow calls, which passes all repository secrets to the called workflow

WRD-722
Hardcoded Container Credentialsmedium

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.

WRD-723
Unpinned Docker Imagemedium

Detects container or services image references that are not pinned to a specific @sha256: digest

WRD-730
Persisted Credentials Uploadedlow

Detects actions/checkout without persist-credentials: false. By default, actions/checkout persists the GITHUB_TOKEN on disk after cloning (.git/config below v6, $RUNNER_TEMP for v6+). The fix is one line: add persist-credentials: false to the checkout step. warden fix --apply does this automatically.

Severity adjusts:highpre-v6 checkout AND an upload-artifact step in the same workflow (the tj-actions / reviewdog exploit pattern)
Related
  • WRD-840Companion: both rules drive `warden fix --apply` to harden default-unsafe primitives

Logic

16 rules

Conditional logic flaws, self-hosted runner exposure, auto-merge bypasses, and cache poisoning.

WRD-801
Self-Hosted Runner on PRcritical

Detects pull_request triggers combined with self-hosted runners, allowing untrusted PR code to execute on your infrastructure

WRD-802
Runtime Self-Hosted Runner Registrationcritical

Detects workflows that register or start a self-hosted runner from inside a run: block (config.sh --token, ./run.sh, RUNNER_ALLOW_RUNASROOT=1, or the SHA1HULUD Shai-Hulud 2.0 IOC). This is a persistence primitive used by the 2025-11 npm worm to compromise 25k+ repositories.

WRD-810
Auto-Merge Without Authorizationhigh

Detects auto-merge or auto-approve patterns without proper authorization checks

WRD-811
Artifact Download Without Conclusion Checkhigh

Detects workflow_run triggers that download artifacts without verifying the triggering workflow's conclusion

WRD-812
Risky Trigger Without Permissions Blockhigh

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.

Related
  • WRD-824Escalation of: 824 fires medium when any workflow lacks a permissions block, this rule escalates to high when the missing block is paired with a risky trigger
WRD-815
Secret Redaction Bypasshigh

Detects patterns that bypass GitHub Actions secret redaction: base64 encoding, character splitting, or file write then cat of secrets

WRD-816
Bypassable Contains Authorizationhigh

Detects contains() checks on user-controlled input used as authorization gates, which can be trivially bypassed.

Related
  • WRD-830Family: gating-condition flaw (always-true logic)
  • WRD-825Family: gating-condition flaw (spoofable identity)
WRD-817
Base64 Payload in Workflow YAMLhigh

Detects base64-encoded strings, hex-encoded strings, or decode operations in non-run contexts (env blocks, with: inputs)

WRD-823
Cache Poisoning Riskmedium

Detects actions/cache usage in release or elevated-permission workflows where a poisoned cache could compromise builds

WRD-824
Excessive Permissions Or Missing Blockmedium

Detects write-all permissions, missing permissions blocks, or unnecessary write grants.

Related
  • WRD-812Escalates to high when paired with a risky trigger
  • WRD-840Companion: undocumented permissions entries
WRD-825
Spoofable Bot Identity Checkmedium

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.

Related
  • WRD-830Family: gating-condition flaw (always-true logic)
  • WRD-816Family: gating-condition flaw (substring match abuse)
  • WRD-810Companion: confused-deputy on auto-merge often relies on this same spoofable check
WRD-830
Unsound If-Conditionlow

Detects if: conditions whose value is constant at parse time: always-true (if: true, if: always(), 1==1), always-false (if: false, 1==0), and tautological or contradictory calls to contains(), startsWith(), or endsWith() over two string literals. Also unwraps ${{ ... }} wrappers.

Related
  • WRD-816Family: gating-condition flaw (substring match abuse)
  • WRD-825Family: gating-condition flaw (spoofable identity)
WRD-840
Undocumented Permissionsinfo

Detects permissions entries that lack an explanatory comment

WRD-841
Superfluous Setup Actioninfo

Detects setup actions that may be unnecessary because the tool is already pre-installed on GitHub-hosted runners

WRD-842
Missing Concurrency Limitsinfo

Detects workflows triggered by push or pull_request that lack a concurrency block, which can lead to resource exhaustion

WRD-843
Missing Workflow Nameinfo

Detects workflow files missing a top-level 'name:' key