Rules / GL080
GL080 Sensitive job with no pipeline-source guard
Severity: warn
OWASP: CICD-SEC-1 – Insufficient Flow Control Mechanisms
Risk
A privileged job with no pipeline-source guard at all runs on every pipeline source — including fork merge requests, where an external contributor controls the code. Without a rules:if that inspects $CI_PIPELINE_SOURCE (or an equivalent restriction), a deploy/publish/release job is an absent flow-control gate: untrusted contributors can trigger it.
What glsec checks
GL080 flags a job when all of the following hold:
- The job is sensitive — it declares a named
environment:(other than anaction: stopteardown), or its name/stage matches a narrow deploy keyword (deploy,rollout,release,publish,provision). Build/test/package jobs are excluded even when their name contains a deploy word (e.g.windows-release-build,docdist). - The job has no effective guard — either no
rules:/only:/except:at all, or arules:block whose items carry noif:/changes:/exists:condition (e.g. onlywhen: always/when: on_success), so the gate imposes no restriction. - No restricting
workflow:rules— the top-levelworkflow:rulesdoes not carry anif:condition that would already gate which pipeline sources run.
To avoid false positives on guards glsec cannot resolve, GL080 skips:
- Hidden jobs (names starting with
.) — templates GitLab never runs. - Jobs that inherit config via
extends:— their guard may come from a base. YAML merge keys (<<:) are resolved, so a guard merged in from an anchor is seen like one written inline.
Trigger example
deploy-prod:
stage: deploy
script:
- ./deploy.sh # no rules: — runs on fork MR pipelines too
publish:
stage: deploy
rules:
- when: on_success # no if: — imposes no source restriction
script:
- ./publish.sh
Safe alternative
Gate the job on the pipeline source (and, for deploys, restrict to the intended branches):
deploy-prod:
stage: deploy
rules:
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "main"'
script:
- ./deploy.sh
A restricting top-level workflow:rules gates every job, in which case GL080 does not fire.
Relationship to other rules
- GL013 flags a production-environment deploy job with no
rules:/only:. GL080 defers to GL013 for that exact case and covers the gaps: jobs sensitive by stage/name (notenvironment:), and jobs whoserules:block exists but imposes no condition. - GL074 flags a tautological (always-true)
rules:if. GL080 covers the missing/ineffective gate — noif:at all — rather than an always-true one. - GL053 flags a missing or unrestricted top-level
workflow:rulesat the pipeline level.
False-positive note
Not every deploy-stage job without rules: is exploitable — many legitimately rely on a restricting workflow:rules (which GL080 already accounts for) or on branch-scoped runners. Review each finding in context.
Documentation for glsec 1.23.0. Source of this page · Rule implementation