GH_PUSH_TO_DEFAULT
Summary
Forestall ACL Alias
GH_PUSH_TO_DEFAULT
Edge Type
Attack Path
Affected Object Types
GitHub Repositories
Exploitation Certainty
Certain
GitHub Role / Permission
Repository write (push) or maintain, on an unprotected default branch
Description
GH_PUSH_TO_DEFAULT represents that a user or team can push code directly to a repository's default branch. The default branch is what CI/CD builds and deploys from, so the ability to write to it without review is a supply-chain foothold.
The edge is created only when both conditions hold:
The entity has write-level permission (
pushormaintain) on the repository, andThe default branch is not protected — there is no branch protection rule gating direct pushes. This is the relational form of the
FS6021(No Branch Protection) finding.
Admin holders are intentionally not given this edge: they are already modelled by GH_ADMIN (full control, which also includes the ability to remove protection and push). Archived repositories cannot be pushed to and are excluded.
When the default branch is protected (required reviews, status checks, or push restrictions), a direct push is blocked and this edge is not created — the writer must go through a reviewed pull request instead.
Identification
GitHub Web Interface
Open the repository → Settings → Branches. If the default branch has no protection rule, direct pushes are allowed.
Open Settings → Collaborators and teams. Any user or team with Write or Maintain can push directly to the unprotected default branch.
GitHub CLI
Check whether the default branch is protected (404 = unprotected):
List teams and collaborators that hold write-level access:
Exploitation
When the default branch is unprotected, a write-level entity can compromise the repository's build and deployment pipeline with a single push:
Inject a malicious GitHub Actions workflow. A workflow pushed to
.github/workflows/runs with the repository's secrets andGITHUB_TOKEN. Where OIDC federation is configured, it can mint a cloud token and pivot out of GitHub entirely.Tamper with shipped code. Backdoor application source on the default branch so the next deploy carries the attacker's payload to production.
Exfiltrate secrets at build time. Print or transmit repository/environment secrets from a workflow step.
Because no review gates the push, the change reaches the default branch (and the pipeline) immediately — hence Certain certainty.
Mitigation
Protect the default branch. Enable a branch protection rule (or a ruleset) on the default branch: require pull requests, require at least one review, and disallow direct pushes. This removes the edge entirely. See
FS6021.Require review for workflow changes. Use
CODEOWNERSto require an owner's review for.github/workflows/so workflow tampering cannot be self-merged.Grant least privilege. Prefer
triage/readoverwritewhere contributors do not need to push. Manage write access through teams, not direct collaborator grants.Constrain Actions and OIDC. Set default workflow permissions to read-only, restrict which actions can run, and scope cloud federated-identity credentials (
subjectclaim) to specific protected branches/environments rather than the whole repository.Include administrators in protection. Enable "Do not allow bypassing the above settings" so even admins cannot push directly to the default branch on sensitive repositories.
Detection
Monitor the GitHub audit log and Git events for direct writes to the default branch:
git.push
A push was received (correlate ref = default branch, no associated PR)
protected_branch.destroy
A branch protection rule was removed (opens this edge)
repo.update_member / team.add_repository
Write-level access was granted
workflows run from an unexpected actor
A new/modified workflow executed shortly after a direct push
Alert on direct pushes to the default branch that are not associated with a reviewed pull request, on any removal of branch protection, and on workflow runs that request id-token: write from an unexpected actor.
References
Last updated
Was this helpful?