glsec

Rules / GL068

GL068 shell xtrace (set -x) enabled in a script

Severity: warn
OWASP: CICD-SEC-6 – Insufficient Credential Hygiene

What glsec checks

glsec flags any command in script, before_script, or after_script (top-level, default:, or job-level), or in a run: step, that turns on shell command tracing:

With xtrace on, the shell prints every command to the job log after variable expansion. Any secret-bearing command then appears in plaintext in the (often public) job log — git push https://user:$TOKEN@host/…, curl -H "Authorization: Bearer $API_TOKEN", deploy --key "$DEPLOY_KEY". This is the script-level twin of CI_DEBUG_TRACE (see GL033), and it is the activation that turns "uses a secret" rules like GL021 and GL035 into an actual leak.

A line whose net effect leaves xtrace off — set -x … ; set +x scoped to a non-secret block on the same line — is not flagged. A bare set -x (or one disabled only on a later, separate line) is.

Trigger example

deploy:
  script:
    - set -euxo pipefail        # flagged — traces expanded commands (incl. secrets) to the log
    - git push "https://ci:${DEPLOY_TOKEN}@gitlab.example/repo.git" HEAD:main

Safe alternative

Prefer set -euo pipefail (no x). If you must trace for debugging, scope it tightly and keep secrets out of the traced region:

deploy:
  script:
    - set -x; ./build.sh; set +x   # traced, no secrets here; tracing is off again at the end of the line
    - deploy --key "$KEY"          # secret-touching command runs with tracing off

References

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