Shelling Out Sucks (2012)
julialang.org
julialang.org
This sentence sounds eerily similar to what we have with SQL Injection. Same concept: constructing raw commands for untrusted user input. The solution is equally simple: input validation (where possible), parameterized queries/shellescape.
The barriers to people shelling out securely are the same we had/have with SQL Injection:
1- Education: Many people are unaware of these solutions.
2- Bad habits reenforced by bad code examples. People don't use these security best practices in the simplified code examples included in a blog post, documentation, or a Stack Overflow answer. I joke that the only SQL code example on MSDN that isn't SQL Injectable was the example for parameterized queries (I'm not that far off). Sadly It's not much better for escaping/defanging shell code.
Shelling out also had the added problem that far fewer people do it than use SQL, so the propagation of security best practices is going to be slower. Luckily it also means there are fewer places that screw it up.
[1] http://julia.readthedocs.org/en/latest/manual/metaprogrammin...
I bother. It's not hard. If you're not escaping outputs, you're part of the problem.
I made substantially the same comment when this article was originally posted ( https://news.ycombinator.com/item?id=3689561 )
1. Not reinventing the wheel
2. Implicit use of multiple cores
Things could be improved I agree.
For example posix_spawn() could be efficiently implemented on glibc to avoid kernel overhead for fork()+exec() from large processes. Then language runtimes could use that to implement their "shell out" routines.
Also pipefail doesn't cater for SIGPIPE as detailed at http://www.pixelbeat.org/programming/sigpipe_handling.html which can be awkward.
In addition to all the points mentioned by the author, another problem with relying on external commands is portability. Even the ubiquitous and UNIX-specified `grep` command contains extensions in OSX and GNU compatibility flags.
Integer(`find #{dir} -type f -print0 | xargs -0 grep foo | wc -l`)
is unlikely to fail because of bad input. result = shell_out('find ? -type f -print0 | xargs -0 grep foo | wc -l', dir_path)
Would automatically `Shellwords.shellescape` interpolated variables, same as ActiveRecord does (hash params could be supported too). Would by default automatically `set -o pipefail` for you too, and perhaps even by default raise for a non-succesful outcome. All of these defaults could hypothetically be changed by option arguments.In fact, I wonder if there already is a gem that does this, that nobody uses? :) If not, it makes me want to write one just for fun, link back to OP as explanation of why you want this. That still nobody would use except me, heh.
Shelling out is a hacky solution nonetheless, with a terrible performance profile, but there are reasons people use it anyway, and a wrapper like this could take care of many common gotchas.
$ mkdir sh
$ cd sh
$ >foo find . -type f -print0
$ >bar head -1 foo foo
$ # four lines with "foo" in file bar
$ >foo echo foo
$ mv foo 'bar
> baz'
$ # one line with "foo" in file bar?baz
$ find . -type f -print0 | xargs -0 grep foo | wc -l
3
$ # Wait a minute that's not five, I KNOW there five lines!
$ find . -type f -print0 | xargs -0 grep foo
Binary file ./bar matches
./bar
baz:foo
$ # oh...
$ find . -type f -exec grep -c foo '{}' \;
4
1
$ # might as well get everything closer to correct
$ env -i /usr/bin/find . -type f -execdir /usr/bin/grep -c foo -- '{}' \; | \
env -i /usr/bin/awk '{t+=$1}END{print t}'
5I do a lot of security things and I attempted to write vulnerable code that shells out to do some purpose with some user provided data concatenation in. I.... Couldn't figure out how. If you figure out how, let me know. More languages should be doing this parametrized approach for shelling out like Go does
Not a Go thing. "Shelling-out" is different.