Documentation

GitHub Rules

Vulnetix GitHub posture rules: workflow injection and privilege flaws, the action supply chain, and repository and organisation settings.

The GitHub rules run in vulnetix gha workflows, actions, settings, org and audit, and in the Vulnetix Software Factory on GitHub App events, from the same engine. Rules marked needs report “not evaluated” when those GitHub settings could not be read, never a pass. Rules marked uses run on the files alone and read the settings, when present, to lower or raise a finding’s severity.

Workflows (vulnetix gha workflows)

RuleSeverityContext
VNX-GH-001 – Untrusted input expanded into an executed scriptCriticaluses repo
VNX-GH-002 – Untrusted input written to GITHUB_ENV or GITHUB_PATHHigh
VNX-GH-003 – Privileged workflow runs code from an untrusted pull requestCriticaluses repo, environments
VNX-GH-004 – Checkout credentials persisted into an uploaded workspaceHigh
VNX-GH-005 – Privileged workflow consumes artifacts from an untrusted runHigh
VNX-GH-006 – Release workflow restores a cache writable by untrusted runsHigh
VNX-GH-007 – Workflow token permissions not declaredMediumuses repo
VNX-GH-008 – Excessive token permissionsMedium
VNX-GH-009 – OIDC token minted outside a protected environmentMediumuses environments
VNX-GH-010 – All secrets passed to a reusable workflowMediumuses repo
VNX-GH-011 – Secrets context exposed in bulkHigh
VNX-GH-012 – Hard-coded container registry credentialsHigh
VNX-GH-013 – Deprecated workflow commands re-enabledHigh
VNX-GH-014 – Authorisation by spoofable actor nameHigh
VNX-GH-015 – Condition always evaluates to trueHigh
VNX-GH-016 – Self-hosted runner reachable from pull requestsHighuses repo, runner groups
VNX-GH-017 – Secret printed to the job logMedium
VNX-GH-018 – Comment-triggered workflow without an author checkHighuses repo
VNX-GH-019 – Obfuscated action reference or expressionLow
VNX-GH-020 – Pull request head ref used as a branch or tag name without quotingMedium
VNX-GH-021 – Secrets sent to an external hostCritical
VNX-GH-022 – Privileged job restores a cache keyed on contributor inputHigh

Actions and images (vulnetix gha actions)

RuleSeverityContext
VNX-GH-101 – Action or reusable workflow not pinned to a commit SHAMediumuses action refs, actions policy, repo
VNX-GH-102 – SHA pin does not match its version commentHighneeds action refs
VNX-GH-103 – Pinned commit is not in the action’s repositoryCriticalneeds action refs
VNX-GH-104 – Action repository archived, missing or hijackableHighneeds action refs
VNX-GH-105 – Action version has a published vulnerabilityHighneeds action refs
VNX-GH-106 – Container image not pinned to a digestLow
VNX-GH-107 – Action major version runs on a retired runtimeLow
VNX-GH-108 – Action not permitted by the allowed-actions policyMediumneeds actions policy
VNX-GH-109 – Action owner resembles a popular publisherHigh
VNX-GH-111 – Remote script piped into an interpreterMedium

Repository settings (vulnetix gha settings)

RuleSeverityContext
VNX-GH-201 – Default branch is not protectedHighneeds repo, branches
VNX-GH-202 – Default branch merges without reviewHighneeds repo, branches
VNX-GH-203 – Approvals survive new commitsMediumneeds repo, branches
VNX-GH-204 – Workflow changes bypass code ownersMediumneeds repo, branches, codeowners
VNX-GH-205 – Force pushes or deletion allowed on the default branchHighneeds repo, branches
VNX-GH-206 – Branch protection can be bypassedMediumneeds repo, branches
VNX-GH-207 – No required status checksLowneeds repo, branches
VNX-GH-208 – Workflow token defaults to writeMediumneeds repo, actions policy
VNX-GH-209 – GitHub Actions can approve pull requestsMediumneeds repo, actions policy
VNX-GH-210 – Fork pull request workflows run without approvalMediumneeds repo, actions policy
VNX-GH-211 – Any action may runLowneeds repo, actions policy
VNX-GH-212 – Secret scanning or push protection disabledMediumneeds repo, security and analysis
VNX-GH-213 – Dependabot alerts or security updates disabledLowneeds repo, security and analysis
VNX-GH-214 – Environment secrets deployable without approvalHighneeds repo, environments
VNX-GH-215 – Deploy key with write access, or unusedMediumneeds deploy keys
VNX-GH-216 – Webhook deliveries can be forged or interceptedMediumneeds webhooks
VNX-GH-217 – Outside collaborator with admin accessMediumneeds collaborators
VNX-GH-218 – Signed commits not requiredLowneeds repo, branches
VNX-GH-219 – Repository secret used by an untrusted-trigger workflowHighneeds repo
VNX-GH-220 – Public repository has no private vulnerability reportingLowneeds repo, security and analysis
VNX-GH-221 – Security policy files missingLowneeds repo, repo files
VNX-GH-222 – Actions secret not rotated in a yearLowneeds secrets

Organisation settings (vulnetix gha org)

RuleSeverityContext
VNX-GH-301 – Organisation does not require two-factor authenticationHighneeds org
VNX-GH-302 – Broad default repository permission for membersMediumneeds org
VNX-GH-303 – Members can create public repositoriesLowneeds org
VNX-GH-304 – Organisation allows any actionMediumneeds org
VNX-GH-305 – Organisation workflow token defaults to writeMediumneeds org
VNX-GH-306 – Organisation secret visible to every repositoryMediumneeds org
VNX-GH-307 – Self-hosted runners available to public repositoriesHighneeds runner groups
VNX-GH-308 – Organisation lets Actions approve pull requestsMediumneeds org
VNX-GH-309 – Organisation webhook deliveries can be forged or interceptedMediumneeds org
VNX-GH-001 – Untrusted input expanded into an executed script
A ${{ }} expression carrying attacker-controlled text is substituted into a shell or script before it runs.
VNX-GH-002 – Untrusted input written to GITHUB_ENV or GITHUB_PATH
Attacker-controlled text is appended to the job's environment or PATH file.
VNX-GH-003 – Privileged workflow runs code from an untrusted pull request
A pull_request_target, workflow_run or comment-triggered job checks out the pull request's code and then executes it.
VNX-GH-004 – Checkout credentials persisted into an uploaded workspace
actions/checkout writes the token into .git/config and the workspace is then uploaded as an artifact.
VNX-GH-005 – Privileged workflow consumes artifacts from an untrusted run
A workflow_run job downloads artifacts produced by a fork-triggered run and extracts them into the workspace.
VNX-GH-006 – Release workflow restores a cache writable by untrusted runs
A workflow that publishes releases restores dependency caches that other workflows on the default branch can write.
VNX-GH-007 – Workflow token permissions not declared
Neither the workflow nor the job declares permissions:, so the token gets the repository default.
VNX-GH-008 – Excessive token permissions
The token is granted write-all, or write scopes at workflow level that every job inherits.
VNX-GH-009 – OIDC token minted outside a protected environment
A job with id-token: write is not bound to an environment with reviewers or a branch policy.
VNX-GH-010 – All secrets passed to a reusable workflow
secrets: inherit hands every repository, environment and organisation secret to the called workflow.
VNX-GH-011 – Secrets context exposed in bulk
toJSON(secrets) or a computed secrets[...] index loads every secret into the job.
VNX-GH-012 – Hard-coded container registry credentials
A job container or service declares a literal password instead of a secret reference.
VNX-GH-013 – Deprecated workflow commands re-enabled
ACTIONS_ALLOW_UNSECURE_COMMANDS re-enables ::set-env and ::add-path.
VNX-GH-014 – Authorisation by spoofable actor name
An if: trusts github.actor == '<bot>[bot]' in a workflow outsiders can trigger.
VNX-GH-015 – Condition always evaluates to true
An if: mixes ${{ }} with surrounding text, or is a block scalar, so it is a non-empty string and always true.
VNX-GH-016 – Self-hosted runner reachable from pull requests
A job triggered by pull requests runs on a self-hosted runner.
VNX-GH-017 – Secret printed to the job log
A run: step prints a secret, relying on log masking to hide it.
VNX-GH-018 – Comment-triggered workflow without an author check
An issue_comment workflow runs privileged steps for any commenter.
VNX-GH-019 – Obfuscated action reference or expression
A uses: path or ${{ }} expression is written in a form that hides what it resolves to.
VNX-GH-020 – Pull request head ref used as a branch or tag name without quoting
A shell variable holding the head branch name is passed to git or gh unquoted or without --.
VNX-GH-021 – Secrets sent to an external host
A step sends the secrets context, the environment, or an encoded secret over the network, or sends any secret to a request-capture host or raw IP.
VNX-GH-022 – Privileged job restores a cache keyed on contributor input
In a pull_request_target, workflow_run or comment-triggered job, a cache key or the cached content is derived from the pull request.
VNX-GH-101 – Action or reusable workflow not pinned to a commit SHA
uses: references a branch or tag, which the action's owner (or anyone who compromises them) can move.
VNX-GH-102 – SHA pin does not match its version comment
uses: owner/repo@<sha> # vX.Y.Z, but vX.Y.Z resolves to a different commit.
VNX-GH-103 – Pinned commit is not in the action's repository
The pinned SHA exists only in a fork of the action repository.
VNX-GH-104 – Action repository archived, missing or hijackable
The referenced action is archived, deleted, or its owner was renamed or removed.
VNX-GH-105 – Action version has a published vulnerability
The referenced version of the action is affected by a known advisory.
VNX-GH-106 – Container image not pinned to a digest
docker:// steps, job containers and services reference an image by tag.
VNX-GH-107 – Action major version runs on a retired runtime
The action version uses a Node.js runtime or backend service GitHub has retired.
VNX-GH-108 – Action not permitted by the allowed-actions policy
The workflow references an action that the repository's allowed-actions policy does not list.
VNX-GH-109 – Action owner resembles a popular publisher
The action's owner is one character away from a widely used publisher.
VNX-GH-111 – Remote script piped into an interpreter
A run: step downloads a script and executes it without verifying it.
VNX-GH-201 – Default branch is not protected
Neither branch protection nor a ruleset applies to the default branch.
VNX-GH-202 – Default branch merges without review
Protection exists but requires no approving review.
VNX-GH-203 – Approvals survive new commits
Stale reviews are not dismissed and approval of the last push is not required.
VNX-GH-204 – Workflow changes bypass code owners
CODEOWNERS does not cover .github/workflows, or code owner review is not required.
VNX-GH-205 – Force pushes or deletion allowed on the default branch
Protection permits force pushes or deleting the branch.
VNX-GH-206 – Branch protection can be bypassed
Administrators are exempt, or a broad role or app is a ruleset bypass actor.
VNX-GH-207 – No required status checks
Pull requests can merge with failing or missing CI.
VNX-GH-208 – Workflow token defaults to write
Workflows without a permissions: block get a read/write token.
VNX-GH-209 – GitHub Actions can approve pull requests
Workflows may create and approve pull requests.
VNX-GH-210 – Fork pull request workflows run without approval
Outside contributors' pull requests run workflows without a maintainer approving them, or private-repo forks get secrets or write tokens.
VNX-GH-211 – Any action may run
The allowed-actions policy permits every action and reusable workflow.
VNX-GH-212 – Secret scanning or push protection disabled
Committed credentials are neither blocked at push time nor alerted on.
VNX-GH-213 – Dependabot alerts or security updates disabled
Vulnerable dependencies, including pinned actions, are not raised as update pull requests.
VNX-GH-214 – Environment secrets deployable without approval
An environment holds secrets but has no required reviewers and no branch policy.
VNX-GH-215 – Deploy key with write access, or unused
A deploy key can push to the repository.
VNX-GH-216 – Webhook deliveries can be forged or intercepted
A repository webhook has no secret, or disables TLS verification.
VNX-GH-217 – Outside collaborator with admin access
Someone outside the organisation can change protection, secrets and settings.
VNX-GH-218 – Signed commits not required
The default branch accepts unsigned commits.
VNX-GH-219 – Repository secret used by an untrusted-trigger workflow
A repository-level secret (not an environment secret) is read by a workflow outsiders can trigger.
VNX-GH-220 – Public repository has no private vulnerability reporting
Researchers have no private channel to report a vulnerability.
VNX-GH-221 – Security policy files missing
SECURITY.md, CODEOWNERS or a Dependabot configuration is absent.
VNX-GH-222 – Actions secret not rotated in a year
A repository secret was last updated more than 365 days ago.
VNX-GH-301 – Organisation does not require two-factor authentication
Members and outside collaborators can sign in with a password alone.
VNX-GH-302 – Broad default repository permission for members
Every member gets write or admin on every repository.
VNX-GH-303 – Members can create public repositories
Any member can publish a repository under the organisation's name.
VNX-GH-304 – Organisation allows any action
The organisation policy permits every action and reusable workflow in every repository.
VNX-GH-305 – Organisation workflow token defaults to write
New repositories inherit a read/write workflow token.
VNX-GH-306 – Organisation secret visible to every repository
An organisation secret has visibility all, so any repository — including public ones — can read it.
VNX-GH-307 – Self-hosted runners available to public repositories
A runner group with self-hosted runners allows public repositories.
VNX-GH-308 – Organisation lets Actions approve pull requests
Workflows across the organisation may create and approve pull requests.
VNX-GH-309 – Organisation webhook deliveries can be forged or intercepted
An organisation webhook has no secret, or disables TLS verification.