|
|
Subscribe / Log in / New account

Simple fix: Only add ./ if bash know is it a file

Simple fix: Only add ./ if bash know is it a file

Posted May 19, 2016 9:57 UTC (Thu) by gmatht (guest, #58961)
In reply to: Safename: restricting "dangerous" file names by farnz
Parent article: Safename: restricting "dangerous" file names

It it seems that there are only two cases
1) Bash knows that the glob is the file, because it had to scan the file system
2) Bash didn't have to scan the file system, so it safe to omit the './'

There are other ways adding ./ could break existing scripts though. For example, the following would no longer give you a list of naughty users:

cd /home; find * -name naughty.jpg | sed s,/.*,,g | sort -u

I guess "bash -n" could warn about unsafe use of "*", warn interactive users, and we could scan all packages for unsafe use of *.


to post comments

Simple fix: Only add ./ if bash know is it a file

Posted May 19, 2016 9:59 UTC (Thu) by farnz (subscriber, #17727) [Link] (5 responses)

You missed case 3 - Bash did not have to scan the file system, but the user's intent was to match a file. For example rm log-{user,system}.txt. There's no way for Bash to detect that sanely without adding in a file system scan - but then the file system scan can cause bash to do the wrong thing for someone who does rm --{force,recursive}.

Simple fix: Only add ./ if bash know is it a file

Posted May 19, 2016 11:18 UTC (Thu) by anselm (subscriber, #2796) [Link] (2 responses)

Of course brace expansion, by definition, has nothing to do with existing files. There are lots of legimitate cases for brace expansion where the expansion results are file names that a file system scan won't uncover, because they don't exist. Consider

$ mkdir -p quarterly-results/201{5,6,7}q{1,2,3,4}

Doing a file system scan here to “validate” the expansion results would be completely pointless if not counterproductive.

Simple fix: Only add ./ if bash know is it a file

Posted May 19, 2016 11:31 UTC (Thu) by farnz (subscriber, #17727) [Link]

Indeed; hence me saying that this isn't actually fixable now. The chance to insist that paths, other strings, and options were distinct entities (with a - hint as first character of an option, and a . hint as the first character of a path, thus not needing a binary protocol to provide the hints) has long since gone away, especially since there are now programs like ps which use the presence or absence of the - to choose between different option parsers.

Simple fix: Only add ./ if bash know is it a file

Posted May 19, 2016 12:55 UTC (Thu) by tao (subscriber, #17563) [Link]

As an additional bonus this will yield different results depending on whether you run it on a basic POSIX-compliant shell or using bash.

touch a b
dash$ ls {a,b}
ls: cannot access '{a,b}': No such file or directory
bash$ ls {a,b}
a b

Case 3=2b

Posted May 20, 2016 4:22 UTC (Fri) by gmatht (guest, #58961) [Link] (1 responses)

Bash doesn't care whether log-user.txt is a file or an option. That is the application's job to decide. Scanning the file system wouldn't even help, for example: `tar x x`.

We don't know that log-{user,system}.txt is an option. We do know that log-{user,system}.txt is a fixed expansion, that doesn't directly depend on any untrusted filenames. So either way we can pass it directly to the application and it handle this ambiguity without worrying too much about the existence of files with malicious names tricking the application.

Case 3=2b

Posted May 20, 2016 8:15 UTC (Fri) by farnz (subscriber, #17727) [Link]

Exactly; if I meant it to be a filename, bash can't tell the application anything that hints that that was my intent. Equally, if I meant it to be an option, bash can't tell the application anything that hints that that was my intent.

Thus, this is currently an insoluble problem, without going back in time and changing the idioms for filenames and options such that filenames *always* began . or / (which then makes log-{user.system}.txt clearly not a filename, as it starts "l"), and options always began -; then, you reserve all other characters for parameters that are neither filenames nor options (e.g. PIDs and IP addresses). This is about 40 years too late now (I wasn't even born when the decisions were being made), so it's an insoluble problem because any shell trying to enforce this needs to cope with the legacy that's already out there.


Copyright © 2025, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds