Re: Can System() of Perl be bypassed?
From: Brian Hatch (secprog@ifokr.org)
Date: 01/22/03
- Previous message: Robert B. Morson: "RE: PGP scripting (reprise)"
- In reply to: Sandeep Giri: "Can System() of Perl be bypassed?"
- Next in thread: NESTING, DAVID M (SBCSI): "RE: Can System() of Perl be bypassed?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Date: Wed, 22 Jan 2003 13:58:01 -0800 From: Brian Hatch <secprog@ifokr.org> To: Sandeep Giri <sandeepgiri@indiatimes.com>
> In my PERL code,I am using user's input as command line argument for the
> program being executed by System().
> Can user run command of his choice by giving malicious input?
> Is PERL's -T (Taint mode) the solution for this?
Using Taint mode is a good thing. However you can still easily
untaint inappropriately:
$user_filename = $q->param('filename');
$user_filename =~ /^ (.*) $/x;
$filename = $1;
system "/bin/ls $filename";
Sure, the filename submitted by the user was untainted and put into
$filename. But since the untainting didn't do anything to actually
check the input (it was just extracted via $1, no checks or munging
whatsoever) a user could easily supply "/etc/passwd; rm -rf /"
as a filename and system will happily process it.
Lesson 1: do real untainting. Make sure the filename looks
exactly like you want it:
$user_filename =~ /^ ([a-zA-Z]+) $/x;
This would allow files that are 100% alphabetic, for example.
No shell metacharacters, no parent (..) directories, or any
directory (/) stuff at all.
Naturally, what a 'valid' value is depends on your needs.
Lesson 2: say what is valid, don't decide what isn't valid.
The best untainting is when you explicitly say what is all right.
If you were trying to extract a suitable filename (anywhere
on the filesystem, including the use of .. and /'s) you'd want
something like this:
/^ ( [\w./]+ ) $/x;
which details exactly what you'd consider valid. If instead
you try to get rid of 'bad' data, such as shell expansion
characters:
/^ ( [^;\$&]+ ) $/x;
Then you're liable to miss some. For example "*" is missing
from the above list.
Lesson 3: always use the array form of system in perl.
System will pass your command to /bin/sh if it thinks there
are shell metacharacters to expand. If you're using user
input, don't do this. (Heck, never do this - it's poor
form anyway.) Instead, use the array version, which will
do a fork/exec of your command explicitly, and never run
the shell. Thus you'd want to have
system( "/bin/ls", $filename);
If somehow your untainting failed, and the user was allowed
to supply "/etc/passwd; rm -rf /" for the filename, you would
end up running
ls "/etc/passwd; rm -rf /"
And, assuming you don't have a file named "/etc/passwd; rm -rf /"
ls will simply complain that no such file exists.
Short answer: unless you program with lots of paranoia, any
programming language can be abused, perl included.
-- Brian Hatch "I've got as much chance of Systems and doing that as seeing a Security Engineer Vorlon doing strip-tease." http://www.ifokr.org/bri/ Every message PGP signed
- application/pgp-signature attachment: stored
- Next message: NESTING, DAVID M (SBCSI): "RE: Can System() of Perl be bypassed?"
- Previous message: Robert B. Morson: "RE: PGP scripting (reprise)"
- In reply to: Sandeep Giri: "Can System() of Perl be bypassed?"
- Next in thread: NESTING, DAVID M (SBCSI): "RE: Can System() of Perl be bypassed?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Relevant Pages
|