Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(escape-cli-args): Always use quotes to escape CLI arguments #53

Merged
merged 5 commits into from
Feb 20, 2023
Merged

fix(escape-cli-args): Always use quotes to escape CLI arguments #53

merged 5 commits into from
Feb 20, 2023

Conversation

pagbrl
Copy link
Member

@pagbrl pagbrl commented Feb 20, 2023

What's the identified issue ?

Mrsk currently does not escape the command line arguments it concatenates for the docker commands.

This make mrsk very susceptible to unescaped characters errors, as the following example demonstrates with an environment string that contains the symbol & :

env:
  clear:
    - THIS_WILL_FAIL=fdjksl&fejkl

Which subsequently creates this docker run issue :

  INFO [a427b772] Running docker run -d --name healthcheck-hello-symfo -p 3999:80 --label service=healthcheck-hello-symfo THIS_WILL_FAIL=fdjksl&fejkl redacted:latest on redacted
  ERROR (SSHKit::Command::Failed): docker exit status: 127
docker stdout: Nothing written
docker stderr: bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
bash: line 1: -e: command not found
bash: line 1: fejkl: command not found
"docker run" requires at least 1 argument.
See 'docker run --help'.

Usage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

Run a command in a new container

This is due to the argumentize function not escaping the characters.

What fix does this PR introduce ?

This PR forces all argumentized CLI arguments to be escaped, thus making the produced commands safe to run.

What's important to note

  • Labels are argumentized the same way that environment variables are, which means I also had to change the way we use traefik labels that use backticks in the code. Result should be 1:1 with what existed before, but I also had to revamp most of the tests to account for this change.
    We might have wanted to make two different argumentize functions, but I don't love it because of code duplication and because I think it's always better to escape characters.

  • In the future we might want to create a special case for integers, but iirc everything that bash passes is a string so I didn't do that here and noticed no behavior

Tests are passing and this has been tested on a mrsk deploy.

@@ -5,7 +5,7 @@ module Mrsk::Utils
def argumentize(argument, attributes, redacted: false)
Array(attributes).flat_map do |k, v|
if v.present?
[ argument, redacted ? redact("#{k}=#{v}") : "#{k}=#{v}" ]
[ argument, redacted ? redact("#{k}=\"#{v}\"") : "#{k}=\"#{v}\"" ]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we need to escape any potential "'s inside the v?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes thank you ! I've used the dump function which does exactly that, and added a gsub escape for backticks which are not escaped by this function.

pagbrl and others added 3 commits February 20, 2023 16:49
* main:
  Bump version for 0.8.0
  Remove images of the same name before pulling a new one
  Changed to a timeout
  Better language
  Switch to ruby-based retry
@dhh dhh merged commit 6f7422a into basecamp:main Feb 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants