Benjamin Smith wrote:
On Tuesday 26 February 2008, Les Mikesell wrote:
WHY THE @!#! NOT?!?!?
The shell is 'supposed' to be run by a user that is allowed to run any
command he wants, and permission/trust issues are handled by the
login/authentication process that happens before you get to the shell.
If you give the shell a bad command under your own account, it's not
supposed to second guess what you wanted.
I'm not asking for this. I'm only asking for the option to be able to trust
that a parameter is... a parameter. EG:
You can, but you have to know how many times shells will parse it. One
layer of quoting is removed each time. Things inside single quotes are
literal, double quotes still do variable expansion.
file: script1.sh
#! /bin/bash
script2.sh $1
exit 0;
file: script2.sh
#! /bin/bash
echo $1;
$ script1.sh "this\ parameter";
I get output of "this"! script2 gets two parameters! I want a way for 1
parameter to STAY 1 parameter upon request, so that script2.sh would
output "this parameter", like
One layer of quotes for each time it is parsed... The first is on the
initial command line, so if you want to hold it together, put double
quotes around "$1".
file:script1.sh
#! /bin/bash
PassToShell2=escapethis $1;
script2.sh $PassToShell;
exit 0;
Bash is used, extensively in many cases, to deal with untrusted data.
Why?
How about an installer script? How about a magical script copied from TLDP to
rename all files in pwd?
These things run with the permissions of the user running them. Why
should they be concerned about that person giving them untrusted
embedded commands that they could just as easily run directly?
This can
include random file names in user home directories, parameters on various
scripts, etc. It's highly sensitive to being passed characters that have,
over the past NN years, resulted in quite a number of security holes and
problems.
If it hurts, don't do it. Build your own argument list and exec
programs directly if you want to avoid shell command line parsing.
So, I'm supposed to know the contents of a user's home directory? And code for
these in advance?
Code so you don't let the shell parse their names. It doesn't have to
if you just want to hand them to some other program.
Yet there exists NO MECHANISM for simply ensuring that a given argument is
an
escaped string?
What does that mean? If you can define it you can make it happen, but
who knows what characters at what depth of quoting will have some
special meaning?
Can I define it? Thought I did that already:
http://us.php.net/manual/en/function.escapeshellarg.php
Can you pass that via ssh to some other system(s) and have i/o
redirection or variable expansions happen in the right places?
Or its perl equivalent:
http://search.cpan.org/~gaas/URI-1.35/URI/Escape.pm
See how I'd like to see it in implementation in above example, "passToShell2"
What's the point? If you are in the shell already it's too late. If
you are in some other program and don't want shell metacharacter
processing to happen, don't feed it to the shell in the first place.
How many "homebrew" ISP or hosting administration scripts could be
compromised
by simply putting a file in your home directory called ";rm -rf /" ?
Probably none that are still in business.
Google "bash howto" for lots of vulnerable and problematic examples. Here's a
beaut that fails if you have a file called "-a" in the pwd, see "File
re-namer". It's a renamer that doesn't, if the file contains any spaces,
dashes, etc.
There are any number of ways to do things wrong. I don't need to look
up more of them.
http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-12.html#ss12.1
Here's what I get:
mv: invalid option -- a
Try `mv --help' for more information.
Most programs accept -- as an option to end option parsing. But if you
don't want this effect, don't start your filenames with a -.
Or with a file with a space:
echo "blah" > "d";
echo "blah" > "d foo";
The TLDP's example doesn't move file "d foo". I get:
mv: cannot stat `d': No such file or directory
mv: cannot stat `foo': No such file or directory
If you don't want the shell to split on spaces you can tell it not to.
Or you can quote filenames correctly. Or not put spaces in filenames.
So I ask again: This doesn't strike you as fundamentally borkeD? The emperor
wears no clothes!
No, it works the way I'd want it to work most of the time. And for the
exceptions, you use quotes in the right places the right number of times.
This doesn't strike you as fundamentally borkeD?
No, if you stop bad things from happening, you'll also stop good things.
Yes. But you don't have to stop the good things.
You don't like the fact that the shell does things like splitting on
white space?
I think the *OPTION* of
saying "parameter 1 is STILL parameter 1" is a good thing. If you want to
leave things be, so be it. See my above example.
You can't do that without knowing at what point you want it to stop
being an opaque blob.
The problem is that you aren't using the shell as intended. If you run
it under your own user id, it does exactly what you tell it to do and
there is no element of trust involved.
The problem, as I see it, is that the shell provides access variables without
any means of preserving them as variables across calls and incantations.
It does. You just have to know when it should and when it shouldn't
Errr what??? Php has about the worst security history of any program
around.
Thanks for confusing the issue with a red herring. Or should I ignore the
buggy and probably vulnerable TLDP example above? Maybe a google search
for "bash escape vulnerability" might illuminate the issue I speak of?
No, you should just learn to use quotes. Or bypass shell processing.
This just blows my mind....
What would you like your computer to prevent you from doing to yourself?
I hate to belabor it: give me the OPTION to trust that I can keep a single
parameter as a single parameter across incantations and calls. If I'm looping
thru a listing files, I should be able to trust that my $FILENAME variable
contains the name of... a file!
A file can be be named pretty much anything, so what does that mean? All
you can do is make sure it is quoted as many times as you let the shell
parse it.
If I want to pass parameter 1 of my script to
another script, that other script should be ABLE get my parameter 1 as...
parameter 1!
OK - quote it.
A simple call that lets me take a string and get a passable parameter would
suffice.
But in shell, such a call would parse whatever you give it - and the
parsing would follow the same rules as every other parsing operation...
You want to apply scripts that break with a space in a file name? Great. Have
at it. I don't want to detract from your ability to make an alphabet soup of
your directories with borken examples from TLDP, and all the goodness that
implies to you.
But I think admins the world over would like it if a simple, one-liner could
be added to ensure that a single parameter remains a single parameter!
Am I being unclear?
You want the shell to not be the shell, I think. Everything the shell
does, it does the same way, which is why we like it in the first place.
You can't tell it to do something without parsing the command and
its arguments.
--
Les Mikesell
lesmikesell@xxxxxxxxx
_______________________________________________
CentOS mailing list
CentOS@xxxxxxxxxx
http://lists.centos.org/mailman/listinfo/centos