Skip to main content
FieldValue
CategoryCICD-SEC-1
SeverityMEDIUM
ConfidenceMEDIUM
Personapedantic
OWASPCICD-SEC-1: Insufficient Flow Control
Auto-fix

What the check does

Flags contains('…literal…', <context>) where the first argument is a literal string haystack and the second is an attacker-influenceable context — a branch ref, PR label, title, and so on.

Why it matters

contains(haystack, needle) performs a substring test when the haystack is a string. If the needle is attacker-controlled, a crafted value that happens to be a substring of the haystack satisfies the check:
# ← a ref like "refs/heads/mai" (or "main-evil") satisfies the substring test
if: contains('refs/heads/main refs/heads/release', github.ref)

Safe alternative

Test membership against an exact list, not a substring:
# array membership — exact match against each element
if: contains(fromJSON('["refs/heads/main","refs/heads/release"]'), github.ref)

# or an explicit comparison
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/release'