Skip to content

Latest commit

 

History

History
42 lines (28 loc) · 1.49 KB

File metadata and controls

42 lines (28 loc) · 1.49 KB

Overview

The GitHub Actions contains() function behaves differently depending on the type of its first argument. When the first argument is a string, contains() performs a substring match rather than an exact membership check. This can be bypassed by an attacker who crafts a value that happens to be a substring of the target string.

For example, the condition contains('refs/heads/main refs/heads/develop', github.ref) would also match github.ref values like refs/heads/mai or refs/heads/evelop, because these are substrings of the target string.

Recommendation

Use fromJSON() to pass an array as the first argument to contains(), which performs an exact array membership check:

if: contains(fromJSON('["refs/heads/main", "refs/heads/develop"]'), github.ref)

Alternatively, use explicit equality checks combined with logical OR:

if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop'

Example

Incorrect Usage

steps:
  - run: terraform apply
    if: contains('refs/heads/main refs/heads/develop', github.ref)

Correct Usage

steps:
  - run: terraform apply
    if: contains(fromJSON('["refs/heads/main", "refs/heads/develop"]'), github.ref)

References