Fix Pipeline Bug
Here are three advanced bug examples and solutions related to modern GitLab CI/CD DevSecOps pipelines with security best practices and explanations. These focus on common pitfalls and necessary configurations for secure, robust pipelines using .gitlab-ci.yml
.
Advanced Bug Example 1: Secrets Leakage via Unprotected Variables
Buggy .gitlab-ci.yml
snippet:
stages:
- build
- deploy
variables:
DB_PASSWORD: "SuperSecretPassword"
build_job:
stage: build
script:
- echo "Building the app..."
- ./build-script.sh
deploy_job:
stage: deploy
script:
- echo "Deploying with password $DB_PASSWORD"
Problem:
- The secret
DB_PASSWORD
is exposed as a plain variable in the.gitlab-ci.yml
file, visible to everyone who can view the repo. - Secrets exposed this way can leak inadvertently, leading to compromise.
Solution:
- Use GitLab CI/CD Protected Variables instead of plain variables.
- Remove secrets from the project file and store them securely via GitLab UI under Settings → CI/CD → Variables, marked as Protected and Masked.
- Modify the
.gitlab-ci.yml
to reference these protected variables without direct value:
stages:
- build
- deploy
build_job:
stage: build
script:
- echo "Building the app..."
- ./build-script.sh
deploy_job:
stage: deploy
script:
- echo "Deploying with password $DB_PASSWORD"
# DB_PASSWORD is set only in GitLab UI, not here.
Explanation:
- Protected Variables ensure secrets are available only on protected branches/environments, reducing exposure.
- Masked Variables prevent secret values from appearing in job logs.
- This practice follows the principle of least privilege and safeguards pipeline secrets.
Advanced Bug Example 2: Unrestricted Pipeline Execution on Untrusted Forks
Buggy .gitlab-ci.yml
snippet:
stages:
- test
test_job:
stage: test
script:
- ./run-tests.sh
Problem:
- The pipeline runs automatically on any fork or merge request, including untrusted contributors.
- This allows potentially malicious code or injections in the pipeline, leading to side-channel attacks or stealing sensitive info.
Solution:
- Use
rules
oronly
/except
keywords to restrict pipeline execution only on trusted branches or defineprotected
for critical branches. - Example with rules to run only on
main
branch or approved MRs:
stages:
- test
test_job:
stage: test
script:
- ./run-tests.sh
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: always
- if: '$CI_MERGE_REQUEST_APPROVED == "true"'
when: always
- when: never
Explanation:
- Restricting pipeline execution avoids running arbitrary code on shared runners.
- Helps prevent pipeline hijacking attacks by malicious forks.
- Combined with branch protection in GitLab UI, this limits pipeline runs to reviewed and trusted code.
Advanced Bug Example 3: Missing Security Scanning Stages Leading to Vulnerability Ignorance
Buggy .gitlab-ci.yml
snippet:
stages:
- build
- test
- deploy
build_job:
stage: build
script:
- make build
test_job:
stage: test
script:
- make test
deploy_job:
stage: deploy
script:
- ./deploy.sh
Problem:
- No security scanning jobs (SAST, Dependency Scanning, Container Scanning) are integrated.
- Vulnerabilities or secrets in code or dependencies can slip into production unnoticed.
Solution:
- Add dedicated security jobs using GitLab’s builtin security scanning templates:
include:
- template: Security/SAST.gitlab-ci.yml
- template: Security/Dependency-Scanning.gitlab-ci.yml
- template: Security/Container-Scanning.gitlab-ci.yml
stages:
- build
- test
- sast
- dependency_scanning
- container_scanning
- deploy
build_job:
stage: build
script:
- make build
test_job:
stage: test
script:
- make test
# SAST, Dependency Scanning, Container Scanning jobs are included from the templates
deploy_job:
stage: deploy
script:
- ./deploy.sh
- Optionally configure the pipeline to fail or block deploy if critical vulnerabilities are found:
sast:
allow_failure: false # Block pipeline on failure
dependency_scanning:
allow_failure: false
container_scanning:
allow_failure: false
Explanation:
- Integrating automated static and dependency scans ensures vulnerabilities are detected early.
- Fail-fast configuration prevents insecure code from reaching production.
- This implements continuous security and DevSecOps principles, embedding security as code in CI/CD pipelines.
Sources:
- GitLab CI security best practices and secrets management
- Modern DevSecOps pipeline principles and security stage integration