Re: Can System() of Perl be bypassed?

From: Brian Hatch (secprog@ifokr.org)
Date: 01/22/03

  • Next message: NESTING, DAVID M (SBCSI): "RE: Can System() of Perl be bypassed?"
    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
    
    




    Relevant Pages

    • Re: Changing Uppercase filenames into Lowercase
      ... uppercase filename to a lowercase filename, ... foundfile = f$searchcommand line. ... Based on a command procedure by Willem Grooters which was ...
      (comp.os.vms)
    • Re: Pass command line file name parameter
      ... Then the document class has a copy of the filename, ... No need to access the original command line at all. ... want the user to see all the labels as they would be printed. ... filename or any other variable of your CWinApp class. ...
      (microsoft.public.vc.mfc)
    • Re: CStdioFile::Open gives error "No error occurred"
      ... I would avoid GetErrorMessage and just use FormatMessage on the error code itself, ... presume this is *not* the filename you planned to open, so why are you using m_lpCmdLine? ... there is a serious question here as to whether or not the command line has any ... Use the debugger, it is a very useful tool. ...
      (microsoft.public.vc.mfc)
    • Re: Cannot delete directory
      ... "Glenn" wrote in message ... > in a command window. ... >>window is a "normal" window. ... >>be a valid 8.3 filename - even if it has somehow been ...
      (microsoft.public.win2000.file_system)
    • Re: command line input and output
      ... Alternatively the first argument was a legal filename but it didn't exist, ... If there were no command line ... Microsoft Powerstation 4.0. ... qomputing dot demon dot co dot uk-- ...
      (comp.lang.fortran)