glsec

Rules / GL082

GL082 Managed security scan disabled by CI/CD variable

Severity: warn OWASP: CICD-SEC-1 – Insufficient Flow Control Mechanisms

What glsec checks

Each GitLab-managed security template gates its jobs on a kill-switch variable:

# from Jobs/SAST.gitlab-ci.yml
rules:
  - if: $SAST_DISABLED == 'true' || $SAST_DISABLED == '1'
    when: never

Set that variable and the scan disappears from the pipeline. glsec flags it in variables: at the top level, under default:, or in a job:

Variable Scan removed
SAST_DISABLED SAST (all analyzers)
SECRET_DETECTION_DISABLED Secret detection
CONTAINER_SCANNING_DISABLED Container scanning
DEPENDENCY_SCANNING_DISABLED Dependency scanning
DAST_DISABLED DAST
DAST_DISABLED_FOR_DEFAULT_BRANCH DAST, on the default branch only
COVFUZZ_DISABLED Coverage-guided fuzzing
API_FUZZING_DISABLED API fuzzing
DAST_API_DISABLED DAST API

Which values count

The templates compare against strings, case-sensitively, so only true and 1 disable anything:

variables:
  SAST_DISABLED: "true"    # flagged — matches the gate
  SAST_DISABLED: "1"       # flagged — matches the gate
  SAST_DISABLED: true      # flagged — YAML boolean, GitLab stringifies it to "true"
  SAST_DISABLED: "True"    # NOT flagged — "True" != 'true', the scan still runs
  SAST_DISABLED: "false"   # NOT flagged

The quoted "True" case is worth knowing about in its own right: it reads as a disabled scan but is not one.

Why it matters

This is the quiet way to lose a scan. GL008 catches allow_failure: true on a scan job and GL039 catches a tool silenced with || true, but both need a job to inspect. Here the job is contributed by an include:d template and never materialises — the pipeline is green, the security dashboard has no new findings, and nothing in the YAML looks broken.

A one-line variable is also cheap to add and easy to forget, which is exactly the shape of change that outlives the incident it was added for.

Trigger example

include:
  - template: Jobs/SAST.gitlab-ci.yml
  - template: Jobs/Secret-Detection.gitlab-ci.yml

variables:
  SAST_DISABLED: "true"           # warn
  SECRET_DETECTION_DISABLED: "1"  # warn

build:
  stage: build
  image: alpine:3.19.1
  script:
    - make

Safe alternative

Keep the scan and narrow what it looks at, rather than switching it off:

variables:
  SAST_EXCLUDED_PATHS: "spec, test, tests, tmp, vendor"

If a scan genuinely does not apply — no supported language, or the scan runs in a different pipeline — suppress it inline with the reason recorded:

variables:
  SAST_DISABLED: "true"  # glsec:ignore GL082 -- no supported language here, SAST runs in the monorepo pipeline

Notes

See also

Documentation for glsec 1.23.0. Source of this page · Rule implementation