glsec

Rules / GL035

GL035 git URL with embedded credentials (user:token@host) in script

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

What glsec checks

glsec flags script lines where a git clone, git push, git fetch, git pull, or git remote command uses a URL containing embedded userinfo credentials in the form https://user:token@host. This exposes the token through:

Note that, by default, the token does not appear in the job log: GitLab echoes the raw script text with the variable unexpanded (e.g. git push https://ci:${TOKEN}@…), and Git itself strips the userinfo from its remote output (To https://gitlab.com/org/repo.git). The risk is real but defence-in-depth — it materialises under debug tracing, with non-redacting tools (curl -v, wget), or via the process table. Even a CI-variable token (not hardcoded) is affected.

Trigger example

deploy:
  script:
    - git push https://ci:${TRANSLATION_TOKEN}@gitlab.com/org/repo.git HEAD:main

Safe alternative

Keep the token out of the URL — and ideally off the command line entirely.

Prefer an SSH remote with a deploy key stored in a protected CI variable (see GL030, GL032); the credential never appears in a URL, in .git/config, or as a command argument:

deploy:
  script:
    - git push git@${CI_SERVER_HOST}:${CI_PROJECT_PATH}.git HEAD:main

Or feed the token to Git through a credential helper / GIT_ASKPASS that reads it from the environment, so it is never written into the URL or persisted:

deploy:
  script:
    - git config credential.helper '!f() { echo "username=gitlab-ci-token"; echo "password=$CI_JOB_TOKEN"; }; f'
    - git push "https://${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git" HEAD:main

Note: git remote set-url origin "https://user:${TOKEN}@host/…" is not a fix — it still embeds the credential in the URL and is flagged by this rule.

References

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