Plugins/docker doesn't hide build-arg secrets with newlines

I have a docker image build running with plugins/docker that specifies a secret for npmrc that contains newlines (itself sourced from Vault). I’ve confirmed that the output has a simple string without newlines for a build_args_from_env is indeed hidden, but the arg for npmrc is not (I’m assuming it’s because the newlines).

- name: build
  image: plugins/docker
  environment:
    NPMRC:
      from_secret: npmrc
    NPM_TOKEN:
      from_secret: npm_token
  settings:
    ...
    build_args_from_env:
      - NPMRC
      - NPM_TOKEN
...

yields the output:

96	 + /usr/local/bin/docker build --rm=true -f styleguide/Dockerfile -t 90755b5ceb28525437aa782b9d22314c058b88c9 styleguide --pull=true --build-arg NPMRC=strict-ssl=false
<remaining verbatim npmrc with secrets>
126	 --build-arg NPM_TOKEN=[secret:npm_token] --label org.label-schema.schema-version=1.0 --label org.label-schema.build-date=2019-12-18T21:40:24Z --label org.label-schema.vcs-ref=90755b5ceb28525437aa782b9d22314c058b88c9

Drone is only capable of masking single-line secrets. If secrets are split across multiple lines they cannot be masked. You could pass the secret as a base64 encoded value to work around this limitation.

Good idea. Thank you.

I have an idea for how we might mask multi-line secrets. I will run some tests and submit a patch to see if we can get it working.

The only thing to note is that masking secrets is at the mercy of buffering and flushing. It is possible the stdout stream could be flushed in a manner that cuts the secret in half, making it impossible for us to detect it. This is an edge case and may never actually surface in the real world, but I feel compelled to document the possibility regardless.

1 Like

I pushed the following patch:

It basically treats each line of a multi-line secret as an individual secret. So instead of searching for the secret, we search for each line individually. This makes it easier to detect multi-line secrets in streams, which are buffered and periodically flushed which otherwise makes this task quite difficult. The unit tests are passing, but will be interesting to see if this approach works in practice.

1 Like

That’s awesome Brad! Thanks for the effort.

How does that effectively get released? In new builds of the drone-runners repos?

we need to update the dependency in our runner repositories, and then publish new minor releases.