5

I have the following situation: I'm storing sensitive data in Gitlab's environment and then passing these variables to a deployment script in bash.

Gitlab's env var:

Key: sensitive_var
Value: aaa$bbb*%

Then in the .gitlab-ci.yml file the env vars are passed to the deployment script as follows:

.deploy:
  script:
    - deploy.sh PASS=${sensitive_var} 

The deployment script parses the arguments as follows:

for arg; do
  TEMP_VAR=$(echo ${arg} | sed -e 's?=? ?')
done

The problem is that when we check the output of the deploy.sh script the variable's value gets expanded resulting in aaa*%.

Solutions tried so far:

  • Storing the value in Gitlab's environment with single quotes ' but then the value was 'aaa*%'.
  • Passing the environment variable with double quotes:
.deploy:
  script:
    - deploy.sh PASS="${sensitive_var}" 
.deploy:
  script:
    - deploy.sh PASS="$sensitive_var" 

But the result was the same: aaa*%.

  • Combination of the above solutions didn't work either.

Why is this happening, and how I can fix it?

3 Answers 3

4

Surprisingly indeed GitLab works weirdly with the env vars.
It evaluates them internally, though it shouldn't in my view.

Value set as (in project Settings > CI/CD > Variables): 'aaa$bbb*%'
becomes 'aaa*%' (with single quotes left!)

Couple of of proof links:

Workarounds:

1) You can duplicate dollar ($) sign, i.e.: aaa$$bbb*%
(as mentioned on the first link above).

2) Use base64 to encode and decode the value.

Do this first:

$ echo 'aaa$bbb*%' | base64
YWFhJGJiYiolCg==

Then store this value in project Variables.

And then in your script decode it:

PASS=$(echo ${sensitive_var} | base64 -D)
10
  • Hi Ivan, thanks for the fast reply. As explained in the problem I already tried enclosing the value in single quotes. It may not be related to Gitlab, but the original value is saved as env var in Gitlab, and then is passed in a job to the deployment script. Also, the script is on a docker image, so it might be possible that I can't access Gitlab's environment from there.
    – JJ Yong
    Commented Jul 16, 2019 at 18:58
  • Where did you enclose the value in single quotes? In CI/CD Settings?
    – Ivan
    Commented Jul 17, 2019 at 7:40
  • Yes, in the env vars of CI/CD settings
    – JJ Yong
    Commented Jul 17, 2019 at 8:08
  • You are right, I've just tested it... funnily it didn't get rid of single-quotes, how you would expect it in bash case... lemme think...
    – Ivan
    Commented Jul 17, 2019 at 13:47
  • See this: gitlab.com/gitlab-org/gitlab-ce/issues/45173#note_101659865
    – Ivan
    Commented Jul 17, 2019 at 13:50
2

This is not answering only the question but also a bit more (I put this here for reference):
I found out a decent way to tackle this and some complications coming afterwards... (after hours and hours of fiddling) - e.g. to execute the script in an SSH session:

deploy job:
  variables:
    # the variables could come from anywhere (e.g. GitLab Settings - environment variables)
    SSH_DIR: '/srv/app/'
    SCRIPT_CMD: |
      echo "Double quotes are safe"
      echo 'Single quotes are safe'
      echo "Code executions are safe -" `whoami`@`hostname` $$(date)
      # the '$$' is needed as otherwise GitLab itself tries variable substitution

  # Here's the magic to get the code from the GitLab variable into a bash variable and then even executed on an SSH session
  script:
    # Put gitlab variable into shell variable to improve quote handling
    - CMD=$SCRIPT_CMD
    # Print for debugging
    - echo -e "Executing:\n$CMD"
    - CMD="set -e; cd $SSH_DIR; $CMD" # 'set -e' = stop on error
    # redirect variable to stdin of ssh bash (the -x causes bash to print each command)
    - ssh -p $SSH_PORT $USERNAME@$SSH_HOST "bash -x" <<< "$CMD"

More detailed example here.

0

One should use protected variables in my opinion. One could configure them in the pipeline settings and subsequently call them inside the pipeline. Using base64 formats should be avoided as these could be easily decrypted.

https://docs.gitlab.com/ee/ci/variables/

1
  • It's a common misconception. Protected env vars in GitLab are not what you think, the main purpose of them is that they are passed only to pipelines of the Protected branches. They are not otherwise protected. There is also a Masked option for env vars which is probably more what you mean, but still it doesn't work all the time - there's a limitation on value, again because it's internally processed by GitLab which it should really do.
    – Ivan
    Commented Jul 18, 2019 at 9:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.