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: taltman
Subject: Re: [bug-gawk] Question regarding security of gawk CGI scripts
Date: Tue, 25 Nov 2014 14:03:08 -0800
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:31.0) Gecko/20100101 Thunderbird/31.2.0

Hello Assaf,

Thank you for all of these examples. I was unaware that the CGI
definition allowed for command-line arguments. I thought one was limited
to only the QUERY_STRING for GET and STDIN for POST methods to pass
information to the script.

For future reference, you can succinctly explain the need for this
feature by referring to Section 4.4 of RFC 3875. I recommend adding that
to the documentation to make it more precise.

http://www.ietf.org/rfc/rfc3875

Cheers,

~Tomer


On 11/20/14 11:27 AM, Assaf Gordon wrote:
> 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]