mediumCWE-693

Missing Branch Protection Rules

Without branch protection on main/production branches, any developer (or compromised account) can push directly, force-push destructive changes, or merge without code review, bypassing all quality and security gates.

How It Works

Branch protection rules are GitHub's mechanism for enforcing review and CI requirements before code reaches important branches. Without them, there is nothing preventing a developer from pushing directly to main, force-pushing to rewrite history, merging a PR without review, or bypassing failing CI checks. If a developer's account is compromised via credential theft or social engineering, the attacker has unrestricted access to modify production code. Even without malicious intent, lack of branch protection means accidental force-pushes, untested code, and unreviewed changes can reach production. This is especially dangerous when CI/CD automatically deploys from main.

Vulnerable Code
# BAD: no branch protection configured (shown as Terraform for GitHub)
resource "github_repository" "app" {
  name       = "production-app"
  visibility = "private"
  # No branch protection resource defined
  # Anyone can push directly to main
  # No required reviews, no status checks
  # Force push is allowed
}
# Result: developers push directly to main
# git push origin main  -- works without review
# git push --force origin main  -- rewrites history
Secure Code
# GOOD: branch protection with required reviews and status checks
resource "github_branch_protection" "main" {
  repository_id  = github_repository.app.node_id
  pattern        = "main"
  enforce_admins = true

  required_pull_request_reviews {
    required_approving_review_count = 1
    dismiss_stale_reviews           = true
    require_code_owner_reviews      = true
  }

  required_status_checks {
    strict   = true  # branch must be up-to-date before merging
    contexts = ["ci/test", "ci/lint", "security/scan"]
  }

  restrict_pushes {
    blocks_creations = true
  }

  allows_force_pushes  = false
  allows_deletions     = false
}

Real-World Example

In the 2020 PHP Git server compromise, attackers pushed malicious commits directly to the php-src repository's main branch, adding a backdoor to the PHP source code. The commits were disguised as typo fixes. This incident led PHP to migrate to GitHub and implement branch protection rules requiring PR reviews. It demonstrated how a single unprotected branch can allow supply chain attacks affecting millions of downstream users.

How to Prevent It

  • Enable branch protection on all main/production branches requiring at least one pull request review before merging
  • Require status checks to pass (CI tests, linting, security scans) before allowing merges
  • Disable force pushes and branch deletions on protected branches to prevent history rewriting
  • Enable 'enforce admins' so that even repository administrators must follow the protection rules

Affected Technologies

GitHub ActionsNode.jsPythonDocker

Data Hogo detects this vulnerability automatically.

Scan Your Repo Free

Related Vulnerabilities