robinson (Jim Robinson) (11/16/90)
In article <25009@adm.brl.mil> K390590%AEARN@pucc.princeton.edu ( Steinparz Franz) writes: >Could someone give me advice how to make a shell script which inherits >its access rights from its owner as this is done by set uid for regular >programs. Just setting the set uid bit via CHMOD 06xxx does not work >on vax under ultrix. I have always been under the impression that setuid shell scripts intentionally do not work for BSD derived unixes in deference to security considerations. However, our experience with ultrix 4.0 (and I believe 2.0) is that *if and only if* "#!/bin/some-shell" is the first line of the script, then setuid will work for that script. However, does this behaviour not violate the whole point of not allowing setuid shell scripts - i.e., that they are a security risk? And, if it was indeed the intention to allow setuid shell scripts, why not go all the way and not require the leading "#!/bin/shell" as is the case with System V? -- Jim Robinson {uunet,ubc-cs}!van-bc!mdivax1!robinson
prl@iis.UUCP (Peter Lamb) (11/16/90)
In article <1990Nov15.181448.23231@mdivax1.uucp>: >In article <25009@adm.brl.mil> K390590%AEARN@pucc.princeton.edu ( Steinparz Franz) writes: >I have always been under the impression that setuid shell scripts >intentionally do not work for BSD derived unixes in deference to security >considerations. The ability to run setuid shell scripts is inherently tied up with the #!/path/name header for a script. I seem to remember that this originated with BSD, but I'm no longer certain. >However, our experience with ultrix 4.0 (and I believe >2.0) is that *if and only if* "#!/bin/some-shell" is the first line of the >script, then setuid will work for that script. This is true. This is true for all BSD derivatives I know. >However, does this behaviour >not violate the whole point of not allowing setuid shell scripts - i.e., >that they are a security risk? And, if it was indeed the intention to >allow setuid shell scripts, why not go all the way and not require the >leading "#!/bin/shell" as is the case with System V? I'm a bit confused by this. I don't think that you need a #! header in SysV for non-setuid shell scripts. I think that it probably still honours the old practice of: 1) The shell tries to exec the script with exec[vl](2). If it has a #! header, the kernel executes the program named in the header and passes it the name of the script as an argument. 2) If the exec() fails, what happens depends on the shell: if you are trying to run the program from Bourne shell, then the shell forks and the child reads the script as commands. if you are using csh, then csh examines the first byte of the file, and if it's a #, then csh forks and reads the file as commands, otherwise it forks, and execs /bin/sh with the pathname of the script as its argument. The reasons behind the strategy in 2) are rather archane; the Bourne shell predated csh, and in *that* (V7) version of the Bourne shell, # was not a comment character; so that csh could run both sh and csh scripts, csh scripts had to start with a #, since this was an unlikely first character for a (V7) sh script (In V7 there was no #!/path/name hack). Confused? I am! You should also note that #! is not restricted to shells. If you can predict what the following #! executable will do, you are well on the way to understanding all this: #!/bin/cat hello squire (You need to put it in a file and make it executable. What happens when you run it? [retorical question :-)]) Those in need of a bit more of a challenge might try: #!/bin/sed /^#/d hello sailor HOWEVER, before you dash off and start making setuid shell scripts: SETUID SHELL SCRIPTS ARE INHERENTLY A SECURITY HOLE! You *CAN'T* make them hackerproof. The only exceptions I know to this are Larry Wall's perl interpreter and Maarten Litmaat's setuid program (but make sure you get his *second* release, not the first, to comp.sources.unix). Since bulletproof /bin/sh and /bin/csh programs are notoriously difficult to write, even in the absence of the kernel problem, my recommendation is perl. Peter Lamb uucp: uunet!mcsun!ethz!prl eunet: prl@iis.ethz.ch Tel: +411 256 5241 Integrated Systems Laboratory ETH-Zentrum, 8092 Zurich
magnus%thep.lu.se@Urd.lth.se (Magnus Olsson) (11/16/90)
In article <6644@ethz.UUCP> prl@iis.UUCP (Peter Lamb) writes: > SETUID SHELL SCRIPTS ARE INHERENTLY A SECURITY HOLE! > > You *CAN'T* make them hackerproof. Why? Magnus Olsson | \e+ /_ Dept. of Theoretical Physics | \ Z / q University of Lund, Sweden | >----< Internet: magnus@thep.lu.se | / \===== g Bitnet: THEPMO@SELDC52 | /e- \q
cjc@ulysses.att.com (Chris Calabrese) (11/18/90)
In article <6644@ethz.UUCP> prl@iis.UUCP (Peter Lamb) writes: >HOWEVER, before you dash off and start making setuid shell scripts: > > SETUID SHELL SCRIPTS ARE INHERENTLY A SECURITY HOLE! > > You *CAN'T* make them hackerproof. > >The only exceptions I know to this are Larry Wall's perl interpreter >and Maarten Litmaat's setuid program (but make sure you get his >*second* release, not the first, to comp.sources.unix). > >Since bulletproof /bin/sh and /bin/csh programs are notoriously >difficult to write, even in the absence of the kernel problem, >my recommendation is perl. >Peter Lamb >uucp: uunet!mcsun!ethz!prl eunet: prl@iis.ethz.ch Tel: +411 256 5241 >Integrated Systems Laboratory >ETH-Zentrum, 8092 Zurich I thought I'd throw my $.02 into this discussion. Yes, it is possible to make them hackerproof. This requires 2 things. First, it requires the the script itself is secure (perl, etc help here). Second, it requires the elimination of the kernel problem. This has been fixed in versions done at bell labs (and subsequently used in the System V Release 4 kernel). The key is that the kernel must pass a file descriptor to the script, not merely the name of the script. This is done by using /dev/fd and passing the appropriate file name for the file descriptor. Under this scheme, since the file is never closed and a descriptor is effectively passed, any foolings with symlinks, naming, etc as has been suggested as the inherent security hole won't work. Of course, it's still difficult to do the right thing with IFS, etc. But at least this makes it _possible_ to write a 100% bullet proof setuid script. Name: Christopher J. Calabrese Brain loaned to: AT&T Bell Laboratories, Murray Hill, NJ att!ulysses!cjc cjc@ulysses.att.com Obligatory Quote: ``pher - gr. vb. to schlep. phospher - to schlep light.philosopher - to schlep thoughts.''
guy@auspex.auspex.com (Guy Harris) (11/18/90)
>I have always been under the impression that setuid shell scripts >intentionally do not work for BSD derived unixes in deference to security >considerations. What actually happened is that due to a particular unclosable-without-"/dev/fd" security hole, Berkeley sent out a 4.xBSD patch to disable set-UID shell scripts, which some vendors have picked up. Prior to that patch, BSD quite happily let you write setuid shell scripts, and happily let anybody who knew the trick get an interactive shell running with the user ID of such a script. >However, our experience with ultrix 4.0 (and I believe 2.0) is that *if >and only if* "#!/bin/some-shell" is the first line of the script, then >setuid will work for that script. That's because if the script doesn't begin with a "#!" line, the shell script isn't "directly executable" - i.e., an "execv()" or "execl()" call specifying that script will fail, while if it begins with a "#!" line, on many systems the "execv()" or "execl()" call will succeed. The way that works on a large number of those systems is that the code that implements "execv()" ("execl()" generally being a wrapper around it) notices the "#!" line, parses it, and runs the program specified by the pathname. That's generally the same code that handles the set-UID bit, so it just runs the program in question set-UID. For non-"#!" scripts, the code that calls "execv()" or "execl()" has to notice the failure and decide to run a shell with that script. The code in question is generally running as ordinary user-mode code and therefore cannot simply decide to run the shell in question set-UID. >However, does this behaviour not violate the whole point of not >allowing setuid shell scripts - i.e., that they are a security risk? It does, but at the time the particular security hole that provoked Berkeley into making the patch in question wasn't known, so it was considered OK to have the system allow shell scripts to be set-UID. >And, if it was indeed the intention to allow setuid shell scripts, why >not go all the way and not require the leading "#!/bin/shell" as is the >case with System V? No System V system with which I'm familiar allows scripts *not* beginning with "#!" to be set-UID. Certainly none of the vanilla from-AT&T versions of S5 I've seen the code of (S5"R1", S5R2, S5R3) do. None of the S5's from AT&T prior to S5R4 even support "#!" in the fashion I described above; S5R4 does, and also, I think, fixes the particular security hole in question. (There may well be other holes nobody's found, or at least told enough people about, yet.) Both System V *and* BSD (and the earlier UNIX systems on their branches of the family tree) have shells that will do the aforementioned operation for scripts that don't begin with "#!", and all but some systems *very* far back on the family tree have routines ("execlp()", "execvp()") that do stuff similar to what the shells do. In other words: Few if any UNIX systems require a "#!" line for executable shell scripts - or, at least, scripts executable as commands by the shells and executable by programs using "execlp()" or "execvp()". Few if any UNIX systems *don't* require a "#!" line for set-UID scripts, although some shells have alternative mechanisms for handling them that may allow them to work without "#!" (e.g., some versions of the Korn shell) and some other programs exist to handle them as well.