4 ms·
Unfortunately he's got this wrong. As long as the server returns a content length (which is up to the project to set up correctly), wget will retry until it get
by cbsmith 13y ago
Unfortunately he's got this wrong. As long as the server returns a content length (which is up to the project to set up correctly), wget will retry until it gets the full length of the script. So the partial execute can't happen.
That's really about as well as you can do, because HTTP doesn't do a good job of reporting errors. You could try to get the content length in advance and then check against it after the download (which is basically what wget is doing), but that won't buy you much. Most servers won't do Content-MD5, so that's out. One smart thing to do would be to use "Accept-Encoding" to download a compressed version of the script and then do a decompression test before running. Alternatively, you can make the download script into a shell archive style script, such that it doesn't do anything until you get to the last byte, at which point it extracts out the real script and runs it (which wouldn't change what your install command is).
The whining about disabling the certificate check is also spurious. Most of the time these are scripts pointing to a non-https URL but which redirect to an HTTPS URL. You are already vulnerable when you do the HTTP request. On top of that, almost nobody is doing DNSSec, so you are already vulnerable at the DNS level. Even ignoring that, Salt offers it as a solution if you can't get the certificate check to work. The alternative would be to provide you with instructions on how to install a CA certificate, which someone is far more likely to screw up and unless you've established trust of the instructions themselves, could be just as vulnerable to a man-in-the-middle attack. Offering instructions on how to disable the check is a perfectly reasonable solution.
- penguindev 13y agoI'm pretty sure wget won't buffer an entire document before writing anything through the pipe to sh. And since it's possible for retries to fail, you have to assume sh could be sent a partial document, followed by EOF, no matter if http/https were used, or chunked/content-length, etc. It is surprising to me that the shell will honor a command line without a newline[1], but it does: $ (echo -n "echo rm -rf /tmp/mydir"; exit 1) | sh OUTPUT: rm -rf /tmp/mydir Obviously if tmpdir got truncated to /tmp, or even /, bad things would happen. [1] Not so suprising when you consider sh -c "command" works without a trailing newline, I suppose.
- cbsmith 13y ago> I'm pretty sure wget won't buffer an entire document before writing anything through the pipe to sh. And since it's possible for retries to fail, you have to assume sh could be sent a partial document, followed by EOF, no matter if http/https were used, or chunked/content-length, etc. Nope. By default wget will literally try forever (you can even shut down your network stack, wait for 10 minutes, and then turn it back on, and wget will proceed from there), and until it closes the stream, the shell interpreter will act as though data is still coming. Any normal way of telling wget to stop will also stop the shell interpreter. Worst case is you end up in some "in the middle" state of the script, but you won't be misinterpreting the script due to early termination of the stream.
- cbsmith 13y agoAnd it's not at all surprising that it honours a command without a newline. Commands are terminated by semicolons, newlines OR EOF. That's pretty much how all shells work. You really wouldn't want the last line of a shell script to be ignored simply because someone didn't put a newline at the end of it.
- cbsmith 13y agoAnd actually, wget will write to stdout with full buffering, which means that small files will actually be completely buffered before writing anything out to sh. That doesn't matter though because the problem that matters is NOT the buffering. Sure that can mean scripts execute partially and then exit, but they will never do something that wasn't intended. The problem the blog is talking about is when you get an EOF in the middle of a script.