4 ms·
1. Shell-escaping all values used to construct commands Avoid shell-escaping and the shell altogether! Use list form program execution wherever possible. In P
by sigil 15y ago
1. Shell-escaping all values used to construct commands
Avoid shell-escaping and the shell altogether! Use list form program execution wherever possible.
In Perl:
open(my $fh, "-|", "find", $dir, "-type", "f", "-print0") or die;
In Python:
f = os.popen2(["find", dir, "-type", "f", "-print0"])
If you're executing a pipeline, you do need to get the shell involved. But I'd probably write the author's examples like so (once again avoiding the need to shell escape arguments):
f = os.popen2(["sh", "-c", \
'find "$0" -type f -print0 | xargs -0 grep foo | wc -l', dir])
2. Prefixing each multi-command pipeline with “set -o pipefail;
Alas, pipefail is not in POSIX /bin/sh, which many of us prefer for shell scripting. It's in bash and ksh though.
3. Explicitly checking for failure after each shelled out command
Valid. You should always do this. In shell scripts, "set -e" is a good thing, although pipelines without "set -o pipefail" are still a problem.
- zwp 15y agoThe article does not address another significant point: filenames should also be classified as untrusted input. Using -- to separate flags from arguments can help: /tmp$ mkdir x /tmp$ cd x /tmp/x$ echo hello > a /tmp/x$ grep hello * hello /tmp/x$ touch -- -q /tmp/x$ grep hello * /tmp/x$ grep hello -- * a:hello /tmp/x$ It's rare to see protection against this problem either when shelling out or in native shell scripts.
- joeyh 15y agoYour quoting of "$0" does not protect it from the shell. An attacker need only provide an input such as: /tmp"; rm -rf /; " There are pipeline libraries that avoid the shell for several languages. Some I can recommend: * libpipeline http://libpipeline.nongnu.org/ http://libpipeline.nongnu.org/ easy, if somewhat verbose, pipeline construction in C. * hsh https://github.com/jgoerzen/hsh/wiki https://github.com/jgoerzen/hsh/wiki makes pipelines in haskell, using operators so they really look like pipelines, but without involving the shell. Example: "ls -l" -|- "wc -l"
- sigil 15y agoYour quoting of "$0" does not protect it from the shell. An attacker need only provide an input such as: /tmp"; rm -rf /; " Not true. $ sh -c 'ls "$0"' '/tmp"; rm -rf /; "' ls: cannot access /tmp"; rm -rf /; ": No such file or directory If you were right, there would be no reasonable way to write shell scripts.
- joeyh 15y agoMy mistake, not knowing python's variable interpoltion well, I thought that the $0 was expanded by it, not the shell. Which, if it were the case, would indeed be vulnerable. Isn't it a bit harsh to downvote to -1 a comment which links to two completly on-topic libraries?
- sigil 15y agoI didn't downvote you, fwiw.
- NinetyNine 15y agoYour comment would be correct if it were PHP.