[comp.unix.questions] How secure are shell scripts?

mferrare@adelphi.ua.oz.au (Mark Ferraretto) (09/26/90)

I want to write a program that all of our users will be accessing and the 
program may be suid to root so that certain users may write to a writeprotected
directory.  At the moment the program is a shell script and I want to know if
this is less secure than writing C code.  Either way the program would have
the protection as 755 though there is no need for the users to read it.

Please mail responses to me and I'll summarise if there is enough interest.

--
       _             Name  : Mark Ferraretto
      \  \           Place : Department of Physics and Mathematical Physics
 ||     \  \                 University of Adelaide
==========>==>==--   Aarnet: mferrare@physics.adelaide.edu.au
 ||      /  /        Phone : +61 8 228 5428
       /_ /          Phax  : +61 8 224 0464


       _             Name  : Mark Ferraretto
      \  \           Place : Department of Physics and Mathematical Physics
 ||     \  \                 University of Adelaide
==========>==>==--   Aarnet: mferrare@physics.adelaide.edu.au

rcpieter@svin02.info.win.tue.nl (Tiggr) (09/28/90)

mferrare@adelphi.ua.oz.au (Mark Ferraretto) writes:

|I want to write a program that all of our users will be accessing and the 
|program may be suid to root so that certain users may write to a writeprotected
|directory.  At the moment the program is a shell script and I want to know if
|this is less secure than writing C code.  Either way the program would have
|the protection as 755 though there is no need for the users to read it.

755 isn't setuid.  Nothing wrong with a non-setuid shell script.  A setuid shell
script owned by root (world executable) enables ANY user to have a root shell
by typing two commands.

Tiggr

maart@cs.vu.nl (Maarten Litmaath) (09/29/90)

In article <1446@svin02.info.win.tue.nl>,
	rcpieter@svin02.info.win.tue.nl (Tiggr) writes:
)...  A setuid shell
)script owned by root (world executable) enables ANY user to have a root shell
)by typing two commands.

You can prevent this by using the indir(1) package from the
comp.sources.unix archives.  Also available through anonymous ftp
from star.cs.vu.nl (192.31.231.42), directory pub/maart, which
contains various vi documents as well.
--
            "the C shell is flakier than a snowstorm."  (Guy Harris)

mferrare@adelphi.ua.oz.au (Mark Ferraretto) (10/10/90)

My original question:

> I want to write a program that all of our users will be accessing and the 
> program may be suid to root so that certain users may write to a
> writeprotected
> directory.  At the moment the program is a shell script and I want to know if
> this is less secure than writing C code.  Either way the program would have
> the protection as 755 though there is no need for the users to read it. 

> Please mail responses to me and I'll summarise if there is enough interest.

Everybody said that a C program is definitely more secure than a shell script
especially when the program is setuid to root.  People suggested setuid to
some group or special user instead of root so that users can still write to
that directory.

darrenr@mullauna.cs.mu.oz.au :

A better way yet, is to give ownership to some user/group so that those users
can write to it.
Or better again, create a new user & group for which this new directory belongs
to and make the program suid to that user/group.

Use root access as your LAST alternative - and then do it VERY carefully.
ie, check every fork()/exec() call it makes to be sure there isn't a way for
the user to get a shell escape - they are EVERYWHERE too.

...rember this : make as little of the
system as possible dependant on root access. (ie have user/group bin own /bin,
/usr/bin, etc...)


Unless you are EXTREMELY careful, yes!
Someone can set a path with, say, their home directory as first thing in path.
They then copy 'sh' into their home directory and call it 'fred', where 'fred'
is some command in the script. Next step, run script and get given an
interactive, fully functioning shell as _root_!!!! Yuk.

Ways around this:
- Be _very_ careful to set PATH explicitly in the script, such that it doesn't
include any directories (especially '.'!) which can _ever_ be writeable to
normal users. 
- Use absolute path names for _every_ single command in the file.
- Write it in C.

I think the last of these is greatly preferable, as there's no way (unless you
write some really silly code) that users can get other programs to run as root.

Another comment: why does it have to be root? If security worries you at all,
make the directory owned by someone else, but not root. Even better, just give
it a special _group_ of its own, and make the program setgid. Then if someone
breaks your program, all they can do is access that directory, not fuck your
whole system up.


Adam Bryant:

I tend to think that C source is much more secure, since any actual
spawning of jobs is totally controlled by the programmer, while this
might not be the case in an insecure shell script.


raymond@math.berkeley.edu:

Suppose your script is in /bin/sh, and is called /usr/local/bin/foo

I type

	ln -s /usr/local/bin/foo -x
	-x

If your #! line is naively set to

	#!/bin/sh

this gives me superuser privileges, since the command line that gets
executed is

	/bin/sh -x


wsinpp@info.win.tue.nl:

At any time prefer C code !. It takes only two commands to become
the user who owns the suid script ! If you have a suid shell script
owned by root. I can become root in just two commands !

King M. Lee <klee@orville.nas.nasa.gov>

Setuid to root is very dangerous.  It may be better to
let a non-root user, say admin, own the directory and 
setuid to admin.

Pat Barron <pat@orac.pgh.pa.us>

Having a setuid shell script is just asking for trouble.  There are a large
number of ways for a random user to subvert a setuid shell script; playing
games with $PATH, fooling with $IFS (in /bin/sh), diddling shell options,
and/or exec'ing the setuid script as "-csh" or "-sh" (thus fooling the shell
into thinking it's interactive, and forcing the execution of any commands
in the user's .login or .profile) are some ways that spring immediately to
mind.  There are countless others.

Write your setuid program in C.  It isn't a perfect solution, but you've
got a much better chance of making it secure than you do if you use a
shell script.

dce@krusty.smsc.Sony.COM

setuid(root) shell scripts are considered dangerous.  Even assuming
that you can write a shell script that isn't potentially broken (for
example, using $* when you mean "$@" or ${1+"$@"}, or things like
test "$x" = "whatIwant"), there are ways for people to get past
security.

While it isn't any less bulletproof to make the shell script setgid and
use group permission, you can make the group generally powerless and
thus stop someone using the script to gain special privilege from
doing much with it.

Supposedly, running the shell script with no special permissions
from a C program that is setuid/setgid is more secure, though I
don't remember why.

If you really are worried, write the C program and save yourself
the anxiety.

Which is exactly what I'll be doing!!

Thanks to everyone for responding
       _             Name  : Mark Ferraretto
      \  \           Place : Department of Physics and Mathematical Physics
 ||     \  \                 University of Adelaide
==========>==>==--   Aarnet: mferrare@physics.adelaide.edu.au

gt0178a@prism.gatech.EDU (Jim Burns) (10/10/90)

in article <1576@sirius.ucs.adelaide.edu.au>, mferrare@adelphi.ua.oz.au (Mark Ferraretto) says:
  [quotes someone as saying]:
> Unless you are EXTREMELY careful, yes!
> Someone can set a path with, say, their home directory as first thing in path.
> They then copy 'sh' into their home directory and call it 'fred', where 'fred'
> is some command in the script. Next step, run script and get given an
> interactive, fully functioning shell as _root_!!!! Yuk.

Note that setuid ksh scripts on HP-UX 7.0 do an automatic 'set -p'
(protected) which, among other things, resets the PATH to something more
trusted (/bin and /usr/bin) and disables sourcing $ENV. This happens
whenever euid != uid. Doesn't solve all the problems, but it is a step in
the right direction.
-- 
BURNS,JIM
Georgia Institute of Technology, Box 30178, Atlanta Georgia, 30332
uucp:	  ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!gt0178a
Internet: gt0178a@prism.gatech.edu

jim@cs.strath.ac.uk (Jim Reid) (10/11/90)

In article <14885@hydra.gatech.EDU> gt0178a@prism.gatech.EDU (Jim Burns) writes:
   Note that setuid ksh scripts on HP-UX 7.0 do an automatic 'set -p'
   (protected) which, among other things, resets the PATH to something more
   trusted (/bin and /usr/bin) and disables sourcing $ENV. This happens
   whenever euid != uid. Doesn't solve all the problems, but it is a step in
   the right direction.

I disagree.

The hack by HP is precisely that: a hack. It fixes one or two possible
problems, but not them all. (For instance doing naughty things with
(symbolic) links to the setuid shell script or replacing the file as
it is being exec'ed....) The end result of that is a false illusion
that setuid ksh scripts are secure. Misguided individuals then make
use of them, thinking the scripts are secure when in fact the scripts
are only marginally safer than if they were executed by the Bourne or
C shells. (Which is nothing to be proud about.)

		Jim

gt0178a@prism.gatech.EDU (Jim Burns) (10/12/90)

in article <JIM.90Oct11150613@baird.cs.strath.ac.uk>, jim@cs.strath.ac.uk (Jim Reid) says:

> The hack by HP is precisely that: a hack. It fixes one or two possible
> problems, but not them all. (For instance doing naughty things with
> (symbolic) links to the setuid shell script or replacing the file as
> it is being exec'ed....) The end result of that is a false illusion
> that setuid ksh scripts are secure. Misguided individuals then make

The first problem can be handled by starting w/'#!/bin/ksh -'. As for the
second, I personally don't have the patience to sit there at adjoining
terminals and try to swap files fast enough. It's like securing your car
or home - all you can do is make it harder, not impossible. If it isn't
setuid scripts that are being exploited, it will be something else.
-- 
BURNS,JIM
Georgia Institute of Technology, Box 30178, Atlanta Georgia, 30332
uucp:	  ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!gt0178a
Internet: gt0178a@prism.gatech.edu

maart@cs.vu.nl (Maarten Litmaath) (10/12/90)

In article <15059@hydra.gatech.EDU>,
	gt0178a@prism.gatech.EDU (Jim Burns) writes:
)in article <JIM.90Oct11150613@baird.cs.strath.ac.uk>,
)	jim@cs.strath.ac.uk (Jim Reid) says:
)
)> The hack by HP is precisely that: a hack. It fixes one or two possible
)> problems, but not them all. (For instance doing naughty things with
)> (symbolic) links to the setuid shell script or replacing the file as
)> it is being exec'ed....) The end result of that is a false illusion
)> that setuid ksh scripts are secure. Misguided individuals then make
)
)The first problem can be handled by starting w/'#!/bin/ksh -'.

That's _not_ enough.

)As for the
)second, I personally don't have the patience to sit there at adjoining
)terminals and try to swap files fast enough.

Why wouldn't you write a little C program or even a shell script?  Jeez!

)It's like securing your car
)or home - all you can do is make it harder, not impossible. If it isn't
)setuid scripts that are being exploited, it will be something else.

No excuse for a lame quasi-solution.
These are _real_ solutions:

	- write a C program instead;
	- use a dispatcher that tries to locate the requested service in
	  a database of setuid scripts;
	- use my `indir' pseudo interpreter front end;
	- acquire a UNIX version that's got the /dev/fd driver and uses
	  that to launch the script.
--
            "the C shell is flakier than a snowstorm."  (Guy Harris)

jmaynard@thesis1.hsch.utexas.edu (Jay Maynard) (10/13/90)

In article <7937@star.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes,
about secure alternatives to setuid shell scripts:
>	- acquire a UNIX version that's got the /dev/fd driver and uses
>	  that to launch the script.

This is a new one on me. What's /dev/fd supposed to do (on those systems where
it's not a floppy disk device), and, if the driver's available somewhere,
where can it be obtained?
-- 
Jay Maynard, EMT-P, K5ZC, PP-ASEL | Never ascribe to malice that which can
jmaynard@thesis1.hsch.utexas.edu  | adequately be explained by stupidity.
"It's a hardware bug!" "It's a    +---------------------------------------
software bug!" "It's two...two...two bugs in one!" - _Engineer's Rap_

gwyn@smoke.BRL.MIL (Doug Gwyn) (10/14/90)

In article <4193@lib.tmc.edu> jmaynard@thesis1.hsch.utexas.edu (Jay Maynard) writes:
>This is a new one on me. What's /dev/fd supposed to do ...
>where can it be obtained?

"/dev/fd/7" is a handle that returns another available file descriptor
that is a duplicate of the current file descriptor # 7.  (Similarly for
other numbers.  Also, /dev/stdin is often provided as a link to /dev/fd/0,
etc.)  I think this first showed up on Research UNIX 8th Edition.  Other
implementations have been provided, for example 4.4BSD probably will have
this.

It is not generally a good idea to try to install a device driver obtained
from elsewhere, unless you are competent to produce the driver yourself.
In the case of /dev/fd, it is pretty easy to implement for yourself.