Unix Wildcards Gone Wild
defensecode.com
defensecode.com
http://www.dwheeler.com/essays/filenames-in-shell.html
I strongly recommend his many other essays to HN readers: http://www.dwheeler.com/
Edit: a simple way to avoid these problems is to prepend the wildcard with ./ (so globbed files won't start with - or -- but with the path ./) and on GNU systems put -- before the wildcard, telling the tool that following arguments are not options.
Looks like the convention was introduced as part of getopt in AT&T Unix System III (1980), though initially only in a handful of places. Then POSIX adopted it as standard for all utilities sometime later.
When --longopt was starting to get popular (in an ad-hoc way) for gnu and other utilities there was a poll (gnu.misc? late 90s?) whether to make it a gnu standard. The other choices were a +, or have commands not accept both bundled single letter options and longopts. There may have been other choices I've forgotten about.
The double-dash won. There were some people who were concerned that it might be confused with the end-of-args double dash.
Maybe that is true but they are certainly unambiguously parsed.
At what point do you give up and, if you must have portability, bootstrap a saner environment?
Are there many options in this area? Assume perl is available? Use autoconf-like shell script compiler? Starting with Lua (which I hope/assume can build anywhere, though I know it's missing lots of functionality out of the box)?
Not embedded devices, but I guess those are different enough that you're probably not targetting them for portable scripts. Oh no, have I contradicted myself? :)
- homepage http://homes.cs.washington.edu/~weise/unix-haters.html
- working download link http://richard.esplins.org/static/downloads/unix-haters-hand...
A lot of it is outdated, and yet many things are still incredibly relevant
1. For “--” to work, all maintainers would have to faithfully use “--” in
practically every command invocation. That just doesn’t happen in real
life, even after decades of people trying. People forget it all the
time; no one is that consistent, especially since code seems to work
without it. Very few commands require it, after all.
So because other people may or may not forget it, I shouldn’t use it in my scripts/day-to-day usage? That’s about as silly as saying that, because other people will write unreadable code anyway I shouldn’t bother with comments, short functions or sensible variable names. 2. You can’t do it anyway, even if you were perfectly consistent; many
programs and commands do not support “--”. POSIX even explicitly for-
bids echo from supporting “--”, and echo must support “-n” (and GNU
coreutils echo supports other options too).
This is a problem, but iff you have to use echo for some reason. printf works nearly equally well and supports -- just fine. I may have read somewhere that using printf is actually advocated nowadays, but I’m not sure where and why.He specifically mentions that that is not his point, but rather that he is arguing against exactly the sort of "just use '--'" response that one can find in this post:
> Do feel free to use “--” between options and pathnames, when you can do it, as an additional protective measure. But using “--” as your primary (or only) mechanism for dash-prefixed filenames is bad idea.
^-- SC2035: Use ./* so names with dashes won't become options.
echo rm *
echo chown -R nobody:nobody *.php
echo chmod 000 *
echo tar cvvf archive.tar *
echo tar cf archive.tar *
echo rsync -t *.c foo:src
This article starts with the premise that the person executing the command has no idea what files are in the current working directory. That is itself a more serious problem than the behaviour of wildcards.Later in the article we learn that it also assumes GNU utilities. That is a second problem (IMO), and arguably also one more serious than the behaviour of wildcards. GNU userland and unneeded complexity (e.g. more features than any user will ever use) are practically synonymous.
Then there is the peculiar assumption that someone can place arbitrary files beginning with - or -- on this system. That itself is a far more serious problem than the behaviour of wildcards; I would say with that capability it is more or less "game over". In BSD you have, at the very least, mtree. How does the Linux user know she isn't executing some substituted executable?
Moreover, if caution was important to the hypothetical user in the examples, I think they would be in the form
/path/to/program *Ahhhh, the memories. These accusations bring me back to the early 1990's. Remember? Remember how it was? Oh, boy, how did we all get so old? To be young and running System V again...
And still today, whenever I'm faced on a system without GNU utilities, I find myself installing them to get what seems to me like basic functionality. We have never changed, have we?
Substitute `person executing the command' with `simple script', and you've got a better justification. I don't want my simple scripts to break down in the face of silly filenames.
Anyway, I didn't think about what happens if you create one file called "-e" and then do
echo *
Anyway, as someone else pointed out, using ./* instead of * will defeat the "exploits" in the article. rsync example.com:/foo/* .
My workaround is to quote the argument, but it's annoying. rsync -a example.com:/foo/. .
rsync example.com:/foo/"*" .rsync accepts globbing it's not a shell expansion that makes it work.
rsync example.com:/foo/\* .Edit: Just remembered that zsh's over-eager globbing also fails with git -- eg., "HEAD^" must be quoted.
There's also `noglob`, which disables glob expansion for a command (e.g. `noglob echo 3*4 | bc`).
[0] http://pubs.opengroup.org/onlinepubs/9699919799/functions/ge...
For example chown username:username files directory -R
Doesn't actually work. You have to move the -R to before the usernames. chown -R username:username files directory.
Same thing with rm.
That said, I going to have to check a few scripts for that chmod attack (or similar) - I think I've seen that type of attack before, but I must have forgotten about it... sigh
Somewhat like sudoedit.
This is of course for the corporate case of a less privileged user performing a certain task at elevated privileges. Not for the more common use of sudo (these days) of people managing their own personal machines.
Can files be created with "-" in Unix? I am using a Linux system and I am not able to do so using vim or touch commands.
touch -- -asdf
It seems like this article is aiming towards shared servers where you actually allow shell login to "untrusted" users, which IMO is a relic of days long past, that only really persists at (maybe) universities. Hell, even at the university I last worked at 6 years ago we just gave everybody their own VM. And nowadays I wouldn't even need to give them that... students can download and run a vagrant environment on their personal machine in like 2 commands.
It's not to say there's no audience for articles like this... I'm sure there's plenty of environments out there that still follow the multi-user server model from the 1970's, and I certainly pity anyone who has to administer those types of systems. But it certainly should be no surprise to anyone that there's a lot of malicious things you can do if you have shell access to a system (or to your point, the ability to upload arbitrarily-named files with arbitrary content. shudder)
Now all you need is a user who kindly requests for a copy of uploaded files. If you're not aware of this issue (and you must be "actively aware" i.e. watch out for it all the time) you can do something that shouldn't be possible.