COMMAND

    guestbook.cgi for Web Servers Using SSI

SYSTEMS AFFECTED

    Systems running guestbook CGI

PROBLEM

    The following text is based on Selena Sol's and CERT sources.

    Guestbook  applications  allow  a  person  browsing  a web site to
    "sign" an electronic guestbook  and leave an appropriate  message.
    A guestbook CGI  script is freely  available by Selena  Sol at the
    following URL:

        http://www.eff.org/~erict/Scripts/guestbook.html

    All  versions  of  this  program  have  a vulnerability that under
    certain  conditions  allows  a  remote  user  to execute arbitrary
    commands on the server as the  user id of the httpd daemon.  These
    conditions are:

      * the server allow Server  Side Includes (SSI) on  the directory
        in which the guestbook is located, and,

      * the  guestbook  application  allows  the  remote user to write
        HTML tags into the Comment field of the guestbook, and,

      * the  guestbook  application  does  not filter appropriate HTML
        tags.

    Remote users may be able to execute arbitrary commands on the  web
    server as  the uid  of the  httpd daemon.   For more  information,
    contact Selena Sol at selena@eff.org

SOLUTION

    Sites using this application should either update their  guestbook
    to  the  current  version  or  implement  the  following  steps as
    appropriate to the version they are using. Note that this may mean
    changing default values within the application.

    (a)  Disable  SSI  on  the   directory  in  which  the   guestbook
        application writes its data. See your WWW server documentation
        for details.

    (b) Filter HTML tags that  can be used to process  arbitrary local
        data:

        $ diff -c guestbook.cgi.old guestbook.cgi
        *** guestbook.cgi.old   Mon Apr 21 15:52:39 1997
        --- guestbook.cgi       Mon Apr 21 16:07:45 1997
        ***************
        *** 88,108 ****

             @form_variables = keys (%form_data);

   ! # For every variable sent to us from the form, and for each word in our
   ! # list of bad words, replace (=~ s/) any occurrence, case insensitively
   ! # (/gi) of the bad word ($word) with the word censored.
   ! # $form_data{$variable} should be equal to what the client filled in in
   ! # the input boxes...
     #
   ! # Further, if the admin has set allow_html to 0, (!= 1) it means that she
   ! # does not want the users to be able to use HTML tags...so, delete them.

             foreach $variable (@form_variables)
               {
               foreach $word (@bad_words)
                 {
                 $form_data{$variable} =~ s/\b$word\b/censored/gi;
                 }
               if ($allow_html != "yes")
                 {
                 $form_data{$variable} =~ s/<([^>]|\n)*>//g;
        --- 88,121 ----

             @form_variables = keys (%form_data);

   ! # For every variable sent to us from the form, filter HTML tags
   ! # that we do not allow regardless of configuration.
     #
   ! # Also, for each word in our list of bad words, replace (=~ s/)
   ! # any occurrence, case insensitively (/gi) of the bad word ($word)
   ! # with the word censored.  $form_data{$variable} should be equal
   ! # to what the client filled in in the input boxes...
   ! #
   ! # Further, if the admin has set allow_html to 0, (!= 1) it means
   ! # that she does not want the users to be able to use HTML tags...so,
   ! # delete them.

             foreach $variable (@form_variables)
               {
        +
        +      # Strip non-negotiable HTML.
        +      # Un-Webify plus signs and %-encoding
        +      $form_data{$variable} =~ tr/+/ /;
        +      $form_data{$variable} =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
        +      $form_data{$variable} =~ $value =~ s/<!--(.|\n)*-->//g;
        +
        +      # Replace bad words.
               foreach $word (@bad_words)
                 {
                 $form_data{$variable} =~ s/\b$word\b/censored/gi;
                 }
        +
        +      # Strip ALL HTML if configured this way.
               if ($allow_html != "yes")
                 {
                 $form_data{$variable} =~ s/<([^>]|\n)*>//g;

    (c) If you do not wish to allow guests to leave HTML tags at  all,
        disable  the  use  of  HTML  tags  in the guestbook by setting
        appropriate  configuration  variables.  You  can  do  this  by
        changing the following line in guestbook.setup:

        $ diff -c guestbook.setup.old guestbook.setup
        *** guestbook.setup.old Wed Aug 14 16:28:13 1996
        --- guestbook.setup     Mon Apr 21 15:51:20 1997
        ***************
        *** 16,22 ****

            $remote_mail = "yes";

        !   $allow_html = yes;

            @required_fields = ("realname", "comments");

        --- 16,22 ----

            $remote_mail = "yes";

        !   $allow_html = no;

            @required_fields = ("realname", "comments");