Cannot use $ character in build variables
Update
Update -
With the implementation of Backend: Make it possible to set a raw variable... (#353991 - closed) it is now possible to use special character when defining a variables in your YAML configuration, the work for this issue is not ever yet, since we want to allow you to do it when you define a variable via the UI (CI/CD - > Settings) you can track this work in Frontend: Make it possible to set variables as ... (#217309 - closed)
Release notes
Previously it was impossible to use the $
character inside a variable since $ sign represent a variable expansion (a reference to another variable), in this release, we are introducing the variable: expand: keyword which will allow you to mark a variable as raw, a raw variable is will not be expanded and can contain any special character
Summary
It's not possible to use the $
character inside a build variable.
Steps to reproduce
- Add a build variable which contains the
$
character somewhere inside. - Add the
env
command to your Gitlab-CI script and watch the output - in the build log you'll see that the variable is trunkated at the
$
sign
Expected behavior
I would either expect a warning or error when trying to save such a build variable.
Or I would expect GitLab to properly escape the content of the build variable.
Actual behavior
The $
sign is obviously treated as a bash variable and is expanded to nothing.
Could this probably a security issue?
Results of GitLab environment info
(For installations with omnibus-gitlab package run and paste the output of:
sudo gitlab-rake gitlab:env:info
)
~# gitlab-rake gitlab:env:info
Your home directory is not set properly:
* `/var/opt/gitlab` is not writable
Bundler will use `/tmp/bundler/home/root` as your home directory temporarily
System information
System: Ubuntu 16.04
Current User: git
Using RVM: no
Ruby Version: 2.3.3p222
Gem Version: 2.6.6
Bundler Version:1.14.3
Rake Version: 10.5.0
Sidekiq Version:4.2.7
GitLab information
Version: 8.16.3
Revision: d225908
Directory: /opt/gitlab/embedded/service/gitlab-rails
DB Adapter: postgresql
URL: https://host.tld
HTTP Clone URL: https://host.tld/some-group/some-project.git
SSH Clone URL: git@host.tld:some-group/some-project.git
Using LDAP: no
Using Omniauth: yes
Omniauth Providers: github
GitLab Shell
Version: 4.1.1
Repository storage paths:
- default: /var/opt/gitlab/git-data/repositories
Hooks: /opt/gitlab/embedded/service/gitlab-shell/hooks/
Git: /opt/gitlab/embedded/bin/git
Workaround
Use base64-encoded values in the UI and base64-decode for jobs.
base64
is in coreutils and available pretty much everywhere without the need to install any additional packages. the cli is simple enough:
❯ base64 <<< 'my $secret text'
bXkgJHNlY3JldCB0ZXh0Cg==
❯ base64 -d <<< bXkgJHNlY3JldCB0ZXh0Cg==
my $secret text
If you want to use this workaround, load the base64-encoded value into the UI, then decode + export the actual value at the beginning of your job, or if you control the call site, at the call site:
export MY_PASSWORD="$(base64 -d <<< "$MY_PASSWORD_B64")"
Designs
Notification Icon | Popover message |
---|---|
User flow:
- User inputs a variable value with
$
sign - The system autodetects this and displays an icon to notify the user about additional settings being available.
- When the user clicks on this icon, a popover is displayed to allow variable substitution.
We need not show the icon when the variable values are hidden. The icon should only be displayed only when the user clicks on the "Reveal values" button or when the user is in the process of adding a new variable and value with a $ sign in it.