Email injection on a contact form

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • stirrell@integrastrategic.com

    Email injection on a contact form

    Hello,

    One problem that I had been having is stopping email injections on
    contact forms. I did some research, read up on it and felt like I had
    created a working solution. I hadn't gotten any suspicious bouncebacks
    in quite some time and got many custom alerts I had set up for
    notifying me of injection attempts. However, just the other day, I got
    a bounceback from an AOL address which leads me to believe that an
    injection attempt was successful. I was hoping that someone here could
    help me out.

    Here is the code that I am using to check for injections:

    function containsInjecti onAttempt($inpu t) {
    if (eregi("\r", $input) ||
    eregi("\n", $input) ||
    eregi("%0a", $input) ||
    eregi("%0d", $input) ||
    eregi("Content-Type:", $input) ||
    eregi("bcc:", $input) ||
    eregi("to:", $input) ||
    eregi("cc:", $input)) {
    return true;
    } // end of if
    else {
    return false;
    } // end of else
    } // end of containsInjecti onAttempt function

    // Check for injection attempts
    if (containsInject ionAttempt($_PO ST['userName']) ||
    containsInjecti onAttempt($_POS T['address']) ||
    containsInjecti onAttempt($_POS T['address2'])
    || containsInjecti onAttempt($_POS T['city']) ||
    containsInjecti onAttempt($_POS T['zip']) ||
    containsInjecti onAttempt($_POS T['phone'])
    || containsInjecti onAttempt($_POS T['email'])) {
    // There has been an injection attempt
    while (list($key, $value) = each($_POST)) {
    $message .= $key.": ".$value."\ n";
    } // end of while
    mail ("me@test.co m", "Injection attempt on Web Site", $message,
    "From: info@website.co m");
    $mailSuccess = 1;
    } // end of if

    Then, if the mailSuccess variable is set to 1, it sends out the email.
    There is also a comments textarea that I do not run through the
    injection check. It is my (possibly incorrect?) understanding that
    anything going into the message body does not need to be checked for an
    injection attempt since it should not be able to affect the headers. A
    problem with checking a textarea against the injection check would be
    that it would mark most legitimate messages as injections since it
    looks for \r and \n. At least this is my understanding.

    I was wondering if someone could tell me if there is a vulnerability in
    the code and, if so, if there is a way to patch it. Thanks so much for
    your help! This has been a frustrating problem that I thought I had
    solved.

    Scott

  • Peter Chant

    #2
    Re: Email injection on a contact form

    stirrell@integr astrategic.com wrote:

    notifying me of injection attempts. However, just the other day, I got
    a bounceback from an AOL address which leads me to believe that an
    injection attempt was successful. I was hoping that someone here could
    help me out.

    Are you sure it is your PHP code, I think my email address must be used as a
    fron or reply-to address by spammers now and again as I get bounce messages
    every so often and I don't have any publically accesable php code that
    could be subjected to email / php / mysql injection.

    Pete


    --

    Comment

    • Miguel Cruz

      #3
      Re: Email injection on a contact form

      Peter Chant <pete@petezilla .co.ukwrote:
      stirrell@integr astrategic.com wrote:
      >notifying me of injection attempts. However, just the other day, I got
      >a bounceback from an AOL address which leads me to believe that an
      >injection attempt was successful. I was hoping that someone here could
      >help me out.
      >
      Are you sure it is your PHP code, I think my email address must be used as a
      fron or reply-to address by spammers now and again as I get bounce messages
      every so often and I don't have any publically accesable php code that
      could be subjected to email / php / mysql injection.
      You can sign up for notifications from AOL which are based on the IP
      address of your server. So then there is no question whether or not you
      are responsible.

      miguel
      --
      Photos from 40 countries on 5 continents: http://travel.u.nu
      Latest photos: Malaysia; Thailand; Singapore; Spain; Morocco
      Airports of the world: http://airport.u.nu

      Comment

      • Miguel Cruz

        #4
        Re: Email injection on a contact form

        stirrell@integr astrategic.com wrote:
        One problem that I had been having is stopping email injections on
        contact forms. I did some research, read up on it and felt like I had
        created a working solution. I hadn't gotten any suspicious bouncebacks
        in quite some time and got many custom alerts I had set up for
        notifying me of injection attempts. However, just the other day, I got
        a bounceback from an AOL address which leads me to believe that an
        injection attempt was successful. I was hoping that someone here could
        help me out.
        >
        Here is the code that I am using to check for injections:
        >
        function containsInjecti onAttempt($inpu t) {
        if (eregi("\r", $input) ||
        eregi("\n", $input) ||
        eregi("%0a", $input) ||
        eregi("%0d", $input) ||
        eregi("Content-Type:", $input) ||
        eregi("bcc:", $input) ||
        eregi("to:", $input) ||
        eregi("cc:", $input)) {
        return true;
        } // end of if
        else {
        return false;
        } // end of else
        } // end of containsInjecti onAttempt function
        >
        // Check for injection attempts
        if (containsInject ionAttempt($_PO ST['userName']) ||
        containsInjecti onAttempt($_POS T['address']) ||
        containsInjecti onAttempt($_POS T['address2'])
        || containsInjecti onAttempt($_POS T['city']) ||
        containsInjecti onAttempt($_POS T['zip']) ||
        containsInjecti onAttempt($_POS T['phone'])
        || containsInjecti onAttempt($_POS T['email'])) {
        // There has been an injection attempt
        while (list($key, $value) = each($_POST)) {
        $message .= $key.": ".$value."\ n";
        } // end of while
        mail ("me@test.co m", "Injection attempt on Web Site", $message,
        "From: info@website.co m");
        $mailSuccess = 1;
        } // end of if
        >
        Then, if the mailSuccess variable is set to 1, it sends out the email.
        There is also a comments textarea that I do not run through the
        injection check. It is my (possibly incorrect?) understanding that
        anything going into the message body does not need to be checked for an
        injection attempt since it should not be able to affect the headers. A
        problem with checking a textarea against the injection check would be
        that it would mark most legitimate messages as injections since it
        looks for \r and \n. At least this is my understanding.
        It looks to me like you are checking a bunch of stuff you don't need to
        - do any of userName, address, address2, city, zip, phone, or email end
        up in the headers of the message you send out? I would assume they all
        end up in the body.

        What you need to look at would be the stuff that does go into the
        headers - a likely suspect would be anything used to build the Subject.

        If you build a "From:" header from the userName or email values then you
        do need to check those.

        miguel
        --
        Photos from 40 countries on 5 continents: http://travel.u.nu
        Latest photos: Malaysia; Thailand; Singapore; Spain; Morocco
        Airports of the world: http://airport.u.nu

        Comment

        • stirrell@integrastrategic.com

          #5
          Re: Email injection on a contact form

          Hello Miguel,

          You're right - I probably am checking more than I need to but I figured
          it didn't hurt to check those inputs and I was trying to make sure I
          wasn't missing anything. Here is a copy of the message from the
          bounceback that I got from the server. To me, it looks like a
          successful injection attempt.

          Return-Path: <anonymous@arth ur.website.com>
          Received: (qmail 13669 invoked by uid 48); 5 Aug 2006 09:20:32 -0400
          Date: 5 Aug 2006 09:20:32 -0400
          Message-ID: <20060805132032 .13668.qmail@ar thur.website.co m>
          To: info@website.co m
          Subject: Inquiry from website Web site:
          From: to@arthur.websi te.com
          Content-Transfer-Encoding: 8bit

          Content-Type: text/plain

          Subject: for the content of




          in violation of applicable laws.











          c38c84c3c20b7d2 88cf34180343fc7 4f

          ..

          <egardless5451@ website.com>

          userName: to

          Content-Transfer-Encoding: 8bit

          Content-Type: text/plain

          Subject: for the content of

          bcc: buletmann@aol.c om



          in violation of applicable laws.

          ---------------------------------------------------

          The email message also contained this error:

          Hi. This is the qmail-send program at arthur.integras trategic.com.
          I'm afraid I wasn't able to deliver your message to the following
          addresses.
          This is a permanent error; I've given up. Sorry it didn't work out.

          <buletmann@aol. com>:
          64.12.138.152 failed after I sent the message.
          Remote host said: 554-: (RLY:CS4)

          554 TRANSACTION FAILED

          --------------------------------------------

          Does this look like a successful injection into the From field? I check
          both the email address and name for an injection attempt. Then I create
          the email like this:

          // Send the email
          $subject = "Inquiry from Web site: $_POST[topic]";
          if (strlen($_POST[userName]) 0) {
          $message .= "Name: $_POST[userName]\n";
          } // end of if
          if (strlen($_POST[address]) 0) {
          $message .= "Address: $_POST[address]\n";
          } // end of if
          if (strlen($_POST[address2]) 0) {
          $message .= "Address 2: $_POST[address2]\n";
          } // end of if
          if (strlen($_POST[city]) 0) {
          $message .= "Name: $_POST[city]\n";
          } // end of if
          if (strlen($_POST[state]) 0) {
          $message .= "State: $_POST[state]\n";
          } // end of if
          if (strlen($_POST[zip]) 0) {
          $message .= "Zip: $_POST[zip]\n";
          } // end of if
          if (strlen($_POST[phone]) 0) {
          $message .= "Phone: $_POST[phone]\n\n";
          } // end of if
          if (strlen($_POST[comments]) 0) {
          $message .= "Comments: ".str_replace(" \r", "",
          $_POST[comments])."\n";
          } // end of if
          if (strlen($_POST[email]) 0) {
          $from = "$_POST[userName] <$_POST[email]>";
          } // end of if
          else {
          $from = "Website <info@website.c om>";
          } // end of else
          $message = stripslashes($m essage);
          mail ("info@website. com", $subject, $message, "From: ".$from);

          So, the from is created via the userName and email variables which are
          checked with the injection check. Can anyone see a flaw that would
          allow someone to create an email like the one that bounced back?

          Thanks so much for your help. I really appreciate the input so far.

          Sincerely,
          Scott

          Miguel Cruz wrote:
          stirrell@integr astrategic.com wrote:
          One problem that I had been having is stopping email injections on
          contact forms. I did some research, read up on it and felt like I had
          created a working solution. I hadn't gotten any suspicious bouncebacks
          in quite some time and got many custom alerts I had set up for
          notifying me of injection attempts. However, just the other day, I got
          a bounceback from an AOL address which leads me to believe that an
          injection attempt was successful. I was hoping that someone here could
          help me out.

          Here is the code that I am using to check for injections:

          function containsInjecti onAttempt($inpu t) {
          if (eregi("\r", $input) ||
          eregi("\n", $input) ||
          eregi("%0a", $input) ||
          eregi("%0d", $input) ||
          eregi("Content-Type:", $input) ||
          eregi("bcc:", $input) ||
          eregi("to:", $input) ||
          eregi("cc:", $input)) {
          return true;
          } // end of if
          else {
          return false;
          } // end of else
          } // end of containsInjecti onAttempt function

          // Check for injection attempts
          if (containsInject ionAttempt($_PO ST['userName']) ||
          containsInjecti onAttempt($_POS T['address']) ||
          containsInjecti onAttempt($_POS T['address2'])
          || containsInjecti onAttempt($_POS T['city']) ||
          containsInjecti onAttempt($_POS T['zip']) ||
          containsInjecti onAttempt($_POS T['phone'])
          || containsInjecti onAttempt($_POS T['email'])) {
          // There has been an injection attempt
          while (list($key, $value) = each($_POST)) {
          $message .= $key.": ".$value."\ n";
          } // end of while
          mail ("me@test.co m", "Injection attempt on Web Site", $message,
          "From: info@website.co m");
          $mailSuccess = 1;
          } // end of if

          Then, if the mailSuccess variable is set to 1, it sends out the email.
          There is also a comments textarea that I do not run through the
          injection check. It is my (possibly incorrect?) understanding that
          anything going into the message body does not need to be checked for an
          injection attempt since it should not be able to affect the headers. A
          problem with checking a textarea against the injection check would be
          that it would mark most legitimate messages as injections since it
          looks for \r and \n. At least this is my understanding.
          >
          It looks to me like you are checking a bunch of stuff you don't need to
          - do any of userName, address, address2, city, zip, phone, or email end
          up in the headers of the message you send out? I would assume they all
          end up in the body.
          >
          What you need to look at would be the stuff that does go into the
          headers - a likely suspect would be anything used to build the Subject.
          >
          If you build a "From:" header from the userName or email values then you
          do need to check those.
          >
          miguel
          --
          Photos from 40 countries on 5 continents: http://travel.u.nu
          Latest photos: Malaysia; Thailand; Singapore; Spain; Morocco
          Airports of the world: http://airport.u.nu

          Comment

          • Miguel Cruz

            #6
            Re: Email injection on a contact form

            stirrell@integr astrategic.com wrote:
            You're right - I probably am checking more than I need to but I figured
            it didn't hurt to check those inputs and I was trying to make sure I
            wasn't missing anything. Here is a copy of the message from the
            bounceback that I got from the server. To me, it looks like a
            successful injection attempt.
            Does look suspiciously that way.
            // Send the email
            $subject = "Inquiry from Web site: $_POST[topic]";
            if (strlen($_POST[userName]) 0) {
            $message .= "Name: $_POST[userName]\n";
            } // end of if
            if (strlen($_POST[address]) 0) {
            $message .= "Address: $_POST[address]\n";
            } // end of if
            if (strlen($_POST[address2]) 0) {
            $message .= "Address 2: $_POST[address2]\n";
            } // end of if
            if (strlen($_POST[city]) 0) {
            $message .= "Name: $_POST[city]\n";
            } // end of if
            if (strlen($_POST[state]) 0) {
            $message .= "State: $_POST[state]\n";
            } // end of if
            if (strlen($_POST[zip]) 0) {
            $message .= "Zip: $_POST[zip]\n";
            } // end of if
            if (strlen($_POST[phone]) 0) {
            $message .= "Phone: $_POST[phone]\n\n";
            } // end of if
            if (strlen($_POST[comments]) 0) {
            $message .= "Comments: ".str_replace(" \r", "",
            $_POST[comments])."\n";
            } // end of if
            if (strlen($_POST[email]) 0) {
            $from = "$_POST[userName] <$_POST[email]>";
            } // end of if
            else {
            $from = "Website <info@website.c om>";
            } // end of else
            $message = stripslashes($m essage);
            mail ("info@website. com", $subject, $message, "From: ".$from);
            >
            So, the from is created via the userName and email variables which are
            checked with the injection check. Can anyone see a flaw that would
            allow someone to create an email like the one that bounced back?
            I think you could make life much simpler by just doing this, and only
            leaving in the characters you know are safe and useful for names and
            email addresses, and trimming each down to 50 characters for good
            measure:

            function clean_header_da ta($str)
            {
            return substr(preg_rep lace('/[^\w .@+\-]/', '', $str), 0, 50);
            }

            Then you can do

            $from = clean_header_da ta($_POST['userName']) . ' <' .
            clean_header_da ta($_POST['email']) . '>';

            Likewise do it with $subject because $_POST['topic'] is untrustworthy.

            After that there's very little way for anything to sneak through.

            --
            Photos from 40 countries on 5 continents: http://travel.u.nu
            Latest photos: Malaysia; Thailand; Singapore; Spain; Morocco
            Airports of the world: http://airport.u.nu

            Comment

            • Steven Musumeche

              #7
              Re: Email injection on a contact form

              stirrell@integr astrategic.com wrote:
              Hello Miguel,
              >
              You're right - I probably am checking more than I need to but I figured
              it didn't hurt to check those inputs and I was trying to make sure I
              wasn't missing anything. Here is a copy of the message from the
              bounceback that I got from the server. To me, it looks like a
              successful injection attempt.
              You should also check the message for BCC, CC, etc. I had a problem in
              which the injection attack was being successfully done in the message
              body part of my contact form.

              -Steven

              Comment

              • Miguel Cruz

                #8
                Re: Email injection on a contact form

                Steven Musumeche <stevenmusumech e@yahoo.comwrot e:
                stirrell@integr astrategic.com wrote:
                >You're right - I probably am checking more than I need to but I
                >figured it didn't hurt to check those inputs and I was trying to
                >make sure I wasn't missing anything. Here is a copy of the message
                >from the bounceback that I got from the server. To me, it looks like
                >a successful injection attempt.
                >
                You should also check the message for BCC, CC, etc. I had a problem in
                which the injection attack was being successfully done in the message
                body part of my contact form.
                Really? That shouldn't happen. If that works, then I could just send you
                an email with a thousand extra bcc's and your defective mail server
                would spam for me, no need for a PHP hole.

                miguel
                --
                Photos from 40 countries on 5 continents: http://travel.u.nu
                Latest photos: Malaysia; Thailand; Singapore; Spain; Morocco
                Airports of the world: http://airport.u.nu

                Comment

                • stirrell

                  #9
                  Re: Email injection on a contact form

                  Hello Miguel and Steven,

                  That's what I thought too - that something put into the body should not
                  be able to affect the headers of the email. But I don't see how else
                  this injection could have been done except through the message body
                  since that is the only object I wasn't checking for an injection
                  attempt (and the script caught a bunch of other attempts made through
                  other fields). I've thought about removing the checks for line breaks
                  and just looking for cc: and bcc: and then including the message body
                  but I didn't know if that would open me up at all.

                  Thank you for the tips. I will put them into place. Though if the
                  injection is through the body (does anyone else think this is
                  possible?) then using Miguel's clean_header_da ta wouldn't stop the
                  injection since it is going through the other form element.

                  Thanks again!

                  Sincerely,
                  Scott

                  Miguel Cruz wrote:
                  Steven Musumeche <stevenmusumech e@yahoo.comwrot e:
                  stirrell@integr astrategic.com wrote:
                  You're right - I probably am checking more than I need to but I
                  figured it didn't hurt to check those inputs and I was trying to
                  make sure I wasn't missing anything. Here is a copy of the message
                  from the bounceback that I got from the server. To me, it looks like
                  a successful injection attempt.
                  You should also check the message for BCC, CC, etc. I had a problem in
                  which the injection attack was being successfully done in the message
                  body part of my contact form.
                  >
                  Really? That shouldn't happen. If that works, then I could just send you
                  an email with a thousand extra bcc's and your defective mail server
                  would spam for me, no need for a PHP hole.
                  >
                  miguel
                  --
                  Photos from 40 countries on 5 continents: http://travel.u.nu
                  Latest photos: Malaysia; Thailand; Singapore; Spain; Morocco
                  Airports of the world: http://airport.u.nu

                  Comment

                  Working...