Skip to content
This repository was archived by the owner on Aug 30, 2024. It is now read-only.

fix: Escape shell arguments #227

Merged
merged 1 commit into from
Jan 25, 2021
Merged

fix: Escape shell arguments #227

merged 1 commit into from
Jan 25, 2021

Conversation

jawnsy
Copy link
Contributor

@jawnsy jawnsy commented Jan 24, 2021

The commands passed to "coder sh" are passed as a single argument to "sh -c", so we need to shell-escape the command we pass. This change escapes spaces, backslash, and quotes.

I'm not 100% sure if this is a good idea, since it is a breaking change in case people have already been escaping their commands.

Note: this will need to be rebased once #226 is merged

Tested as follows:

[coder@jawnsy-m coder-cli]$ go install ./cmd/coder
[coder@jawnsy-m coder-cli]$ which coder
/home/coder/go/bin/coder
[coder@jawnsy-m coder-cli]$ coder sh jawnsy-m go run ~/test.go 1 2 "3 4" '"abc def" \\abc' 5 6 "7 8 9"
warning: version mismatch detected
  | Coder CLI version: unknown
  | Coder API version: 1.14.0+340-gd64a44cb3-20210123
  | 
  | tip: download the appropriate version here: https://github.com/cdr/coder-cli/releases
argv[0] = /tmp/go-build627553793/b001/exe/test
argv[1] = 1
argv[2] = 2
argv[3] = 3 4
argv[4] = "abc def" \\abc
argv[5] = 5
argv[6] = 6
argv[7] = 7 8 9
[coder@jawnsy-m coder-cli]$ go run ~/test.go 1 2 "3 4" '"abc def" \\abc' 5 6 "7 8 9"
argv[0] = /tmp/go-build909559834/b001/exe/test
argv[1] = 1
argv[2] = 2
argv[3] = 3 4
argv[4] = "abc def" \\abc
argv[5] = 5
argv[6] = 6
argv[7] = 7 8 9

For comparison, this is what sh -c and exec would look like:

[coder@jawnsy-m coder-cli]$ sh -c "go run ~/test.go 1 2 \"3 4\" '\"abc def\" \\abc' 5 6 \"7 8 9\""
argv[0] = /tmp/go-build754337722/b001/exe/test
argv[1] = 1
argv[2] = 2
argv[3] = 3 4
argv[4] = "abc def" \abc
argv[5] = 5
argv[6] = 6
argv[7] = 7 8 9
[coder@jawnsy-m coder-cli]$ bash
[coder@jawnsy-m coder-cli]$ exec go run ~/test.go 1 2 "3 4" '"abc def" \\abc' 5 6 "7 8 9"
argv[0] = /tmp/go-build905411501/b001/exe/test
argv[1] = 1
argv[2] = 2
argv[3] = 3 4
argv[4] = "abc def" \\abc
argv[5] = 5
argv[6] = 6
argv[7] = 7 8 9

And this was the previous behavior:

[coder@jawnsy-m coder-cli]$ which coder
/opt/coder/coder-cli/coder
[coder@jawnsy-m coder-cli]$ coder sh jawnsy-m go run ~/test.go 1 2 "3 4" '"abc def" \\abc' 5 6 "7 8 9"
warning: version mismatch detected
  | Coder CLI version: v1.15.0-8-gae35620
  | Coder API version: 1.14.0+340-gd64a44cb3-20210123
  | 
  | tip: download the appropriate version here: https://github.com/cdr/coder-cli/releases
argv[0] = /tmp/go-build394408240/b001/exe/test
argv[1] = 1
argv[2] = 2
argv[3] = 3
argv[4] = 4
argv[5] = abc def
argv[6] = \abc
argv[7] = 5
argv[8] = 6
argv[9] = 7
argv[10] = 8
argv[11] = 9

@shortcut-integration
Copy link

This pull request has been linked to Clubhouse Story #6190: Subtle bug(?) with coder sh handling of spaces.

@jawnsy jawnsy self-assigned this Jan 24, 2021
// $ coder sh go run ~/test.go 1 2 "3 4" '"abc def" \\abc' 5 6 "7 8 9"
func shellEscape(arg string) string {
r := strings.NewReplacer(`\`, `\\`, `"`, `\"`, `'`, `\'`, ` `, `\ `)
return r.Replace(arg)

Choose a reason for hiding this comment

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

I think eventually we should be relying on shlex (or similar) to be parsing and escaping shell commands from strings into arg arrays, and avoid rolling our own for things like this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@tychoish Agree, I did a quick search bit didn't find any good ones. Happy to switch over now, or we can do it later, WDYT?

Choose a reason for hiding this comment

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

https://github.com/google/shlex is functional.

I think this might also solve the %q question in the other PR

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@tychoish Oh yeah, that looks much better. Looks like there were a few cases that I missed.

I don't think this will work for #226 because we need the shell to interpret the subshell calls for getent/etc, but I will give it a try

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm it looks like shlex is for parsing shell expressions, how do I use it to escape things?

The commands passed to "coder sh" are passed as a single argument
to "sh -c", so we need to shell-escape the command we pass.
This change escapes spaces, backslash, and quotes.
@jawnsy jawnsy marked this pull request as ready for review January 25, 2021 16:21
@jawnsy jawnsy merged commit 460c53f into master Jan 25, 2021
@jawnsy jawnsy deleted the jawnsy/ch6190 branch January 25, 2021 16:23
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants