Skip to content

Instantly share code, notes, and snippets.

@btm
Last active December 31, 2015 02:39
Show Gist options
  • Save btm/7922336 to your computer and use it in GitHub Desktop.
Save btm/7922336 to your computer and use it in GitHub Desktop.
Could a well timed network failure turn curl | bash into a destructive accident?

There is an assertation that one reason the "curl | sudo bash" pattern is bad is because you may experience network failure and execute a partially downloaded script.

This:

rm -rf /tmp/random_directory

Could accidentally become:

rm -rf /

I would argue you've got a better chance of winning lotteries than having a network failure while downloading a small script, that happened to have an "rm -rf /...", especially on that particular character. This is a very contrived risk.

For the practical case, I wrote a brief ruby server to return portions of the Chef install.sh script. This script has a lot of logic, so as you can see what usually happens is you break it up is a parse error. In fact, all most all of the script is in conditionals, so you're pretty well garunteed a parse error.

If you take the one part of the Chef install.sh script that contains a destructive statement out and use that, you get errors. For that matter, you're only going to get errors if the connection fails anywhere on the rm line. This kind of example fails similarly:

tmp_dir=/tmp/foo

if [ "$tmp_dir" != "/tmp" ];
then
  rm -r "$tmp_dir"
fi

Wrapping the whole script in a conditional inadvertently give you protection against a network interruption.

As an aside, it is a little disappointing that curl doesn't exit without printing in case of a read error when run in fail mode, but I understand you don't normally want to buffer all that data until you're sure of success.

#!/usr/bin/ruby
require 'socket'
install_script = File.read("install.sh")
server = TCPServer.new 2000
num_c = 0
fail_c = rand(install_script.length)
loop do
Thread.start(server.accept) do |client|
install_script.each_char do |c|
client.syswrite(c)
num_c += 1
if num_c == fail_c
$stderr.puts "bailing out at char: #{num_c}"
exit 1
end
end
client.close
end
end
$ while true; do curl -s localhost:2000 | sudo bash ; sleep 1; done
bash: line 56: unexpected EOF while looking for matching `"'
bash: line 57: syntax error: unexpected end of file
bash: line 24: unexpected EOF while looking for matching `}'
bash: line 25: syntax error: unexpected end of file
bash: line 50: unexpected EOF while looking for matching `"'
bash: line 51: syntax error: unexpected end of file
bash: line 100: unexpected EOF while looking for matching `)'
bash: line 101: syntax error: unexpected end of file
bash: line 46: unexpected EOF while looking for matching `}'
bash: line 47: syntax error: unexpected end of file
bash: line 56: unexpected EOF while looking for matching `"'
bash: line 57: syntax error: unexpected end of file
bash: line 22: unexpected EOF while looking for matching `"'
bash: line 23: syntax error: unexpected end of file
bash: line 79: unexpected EOF while looking for matching `)'
bash: line 80: syntax error: unexpected end of file
bash: line 77: unexpected EOF while looking for matching `"'
bash: line 78: syntax error: unexpected end of file
bash: line 78: syntax error: unexpected end of file
bash: line 39: unexpected EOF while looking for matching `"'
bash: line 40: syntax error: unexpected end of file
bash: line 28: syntax error: unexpected end of file
bash: line 128: syntax error: unexpected end of file
bash: line 102: unexpected EOF while looking for matching `"'
bash: line 103: syntax error: unexpected end of file
bash: line 72: unexpected EOF while looking for matching ``'
bash: line 73: syntax error: unexpected end of file
bash: line 46: unexpected EOF while looking for matching `}'
bash: line 47: syntax error: unexpected end of file
bash: line 83: unexpected EOF while looking for matching `"'
bash: line 84: syntax error: unexpected end of file
bash: line 80: syntax error: unexpected end of file
bash: line 80: unexpected EOF while looking for matching `)'
bash: line 81: syntax error: unexpected end of file
bash: line 79: unexpected EOF while looking for matching `)'
bash: line 80: syntax error: unexpected end of file
bash: line 88: unexpected EOF while looking for matching `)'
bash: line 89: syntax error: unexpected end of file
bash: line 51: syntax error: unexpected end of file
bash: line 44: shell_filenam: command not found
bash: line 79: unexpected EOF while looking for matching `)'
bash: line 80: syntax error: unexpected end of file
bash: line 52: unexpected EOF while looking for matching `"'
bash: line 53: syntax error: unexpected end of file
bash: line 46: unexpected EOF while looking for matching `"'
bash: line 47: syntax error: unexpected end of file
bash: line 33: unexpected EOF while looking for matching `"'
bash: line 34: syntax error: unexpected end of file
bash: line 56: unexpected EOF while looking for matching `"'
bash: line 57: syntax error: unexpected end of file
bash: line 45: unexpected EOF while looking for matching `"'
bash: line 46: syntax error: unexpected end of file
bash: line 53: unexpected EOF while looking for matching `"'
bash: line 54: syntax error: unexpected end of file
bash: line 78: syntax error: unexpected end of file
bash: line 46: unexpected EOF while looking for matching `}'
bash: line 47: syntax error: unexpected end of file
bash: line 114: unexpected EOF while looking for matching `)'
bash: line 115: syntax error: unexpected end of file
bash: line 88: unexpected EOF while looking for matching `)'
bash: line 89: syntax error: unexpected end of file
bash: line 95: syntax error: unexpected end of file
bash: line 83: syntax error: unexpected end of file
bash: line 85: syntax error: unexpected end of file
bash: line 79: unexpected EOF while looking for matching `)'
bash: line 80: syntax error: unexpected end of file
bash: line 81: syntax error: unexpected end of file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment