> 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
This archive was generated by hypermail 2b30 : Wed Jan 22 2003 - 14:27:32 PST