Unprotected branch

ID

unprotected_branch

Severity

critical

Family

SCM

Tags

branch-protection, cicd-sec-01, cicd-security, code-reviews, security, source-code, supply-chain

Description

Does the project use branch protection?

This check determines whether a project’s default and release branches are protected with source repository’s branch protection settings. Branch protection is essential against code tampering.

A few branches should be protected, like the main / default and release branches (often used to deploy into production). Feature or bug fixing branches do not need to be protected, but when merging them into a protected branch, the established rules will be enforced.

When no branch protection a misconfiguration will be emitted. Secondary ones will be emitted, with lower severity than when no branch protection exists at all, for the branch protection rules not matching the expected setup.

You can configure different points to check:

  • Force push must be disabled.

  • Branch delete must be disabled.

  • Settings must also apply to administrators for the branch.

  • Reviews are required for allowing a pull request to merge into a branch.

  • The minimum number of reviews that need to concur for allowing a pull request to merge into a branch.

  • Code owners must review changes done on sensitive code or configuration.

  • Stale review dismissal must be enabled for the branch (need admin permissions).

  • It is required for branches to be up-to-date with the base branch before merging.

Reference: Scorecard Checks page.

Security

Branch protection allows maintainers to define rules that enforce certain workflows for branches, such as requiring review or passing certain status checks before acceptance into a main branch, or preventing rewriting of public history.

Different types of branch protection protect against different risks:

  • Require code review: requires at least one reviewer, which greatly reduces the risk that a compromised contributor can inject malicious code. Review also increases the likelihood that an unintentional vulnerability in a contribution will be detected and fixed before the change is accepted.

  • Prevent force push: prevents use of the --force option on public branches, which overwrites code irrevocably. This protection prevents the rewriting of public history without external notice.

  • Require status checks: ensures that all required CI tests are met before a change is accepted.

Version control systems like Git use branches for change isolation. Changes may be merged into a target branch. But important branches, like main or deployment branches should be protected against uncontrolled modifications. Otherwise, users with write access may delete significant branches or delete the commit history, typically by forced push of changes. Code pushed may be untested, may contain malicious code, or include secrets and other sensitive information that should not be committed to the repository.

Most Git-based hosting services, like GitHub, GitLab or BitBucket, allow to add protection rules for avoiding certain operations on important branches.

To avoid security issues, branch protection rules could be added. These rules provide the following benefits:

  • Avoid unnecessary code commits to the branch

  • Enforce code reviews before merging the code to the branch

  • Maintain a healthy codebase without affecting collaboration

  • Keep commit history (by disallowing force pushes)

  • Makes harder for hard coded secrets from leaking into (public) repositories

Mitigation / Fix

The worst case is when no branch protection is set for the default or any release branch.

Even when branch protection is set for a branch, not following the recommended configuration could be even worse, as it may give a false sense of security.

The configuration specifies the minimal protection rules that on the configured branches that will raise issues when not enabled are:

  • Prevent force push

  • Prevent branch deletion

  • Status checks defined

  • Have one (or more) reviewers

  • Dismiss stale reviews

Follow the instructions to add protected branches rules for Azure | BitBucket | GitHub | GitLab.

Please note that in certain special cases the rules may need to be suspended. For example, if a past commit includes illegal or critical content, it may be necessary to use a force push to rewrite the history rather than simply hide the commit.

Configuration

To change these options you can modify SCANNER_DIR/conf/misconfigurations/unprotected_branch.yml. The following are the default configuration properties:

# Configuration for the checks on branch protection.
properties:
  # If true, force push must be disabled
  forcePushDisabled: true
  # If true, branch delete must be disabled
  branchDeleteDisabled: true
  # If true, settings must also apply to administrators for the branch
  # For GitHub, retrieving this information needs administrator permissions
  enforceAdmins: false
  # If true, reviews are required for allowing a pull request merge into branch
  requiredApprovingReviewCount: true
  # The minimum number of reviews that need to concur for allowing a pull request merge into branch
  minReviews: 1
  # If true, code owners must review changes done on sensitive code or configuration
  requireCodeOwnerReviews: true
  # If true, stale review dismissal must be enabled for the branch (need admin permissions)
  dismissStaleReviews: false
  # If true, it is required for branches to be up-to-date with the base branch before merging.
  upToDateBeforeMerge: false