Jump to content

Example: why you should check/filter form input


Guest So Called

Recommended Posts

Guest So Called

Here is a typical HTML/PHP mail form taken from the W3Schools mail() writeup:

<html><body> <?phpif (isset($_REQUEST['email']))//if "email" is filled out, send email  {  //send email  $email = $_REQUEST['email'] ;  $subject = $_REQUEST['subject'] ;  $message = $_REQUEST['message'] ;  mail("someone@example.com", $subject,  $message, "From:" . $email);  echo "Thank you for using our mail form";  }else//if "email" is not filled out, display the form  {  echo "<form method='post' action='mailform.php'>  Email: <input name='email' type='text' /><br />  Subject: <input name='subject' type='text' /><br />  Message:<br />  <textarea name='message' rows='15' cols='40'>  </textarea><br />  <input type='submit' />  </form>";  }?> </body></html>

It looks reasonable enough, right? Let's attack that from another site. We'll just modify the code from above, and we can throw away the evaluation part since our attack form isn't going to submit to itself. Instead, it's going to submit to the above script.

<html><body> <?php  echo "<form method='post' action='http://example.com/mailform.php'> // I've added the URL of the site to be attacked  Email: <textarea name='email'></textarea><br /> // I've changed the <input> to <textarea>  Subject: <input name='subject' type='text' /><br />  Message:<br />  <textarea name='message' rows='15' cols='40'>  </textarea><br />  <input type='submit' />  </form>";?> </body></html>

What has that accomplished? Note that the top listing takes the form user's "from" email and adds that as a header. Here is the full PHP mail function call: mail(to,subject,message,headers,parameters) In the site being attacked the PHP script gives full access to stuffing as many headers as the attacker wants. Headers are separated by newline characters. By turning the <input> into <textarea> the attacker can add additional headers to $_REQUEST['email'] as follows: Email:

nobody@example.comTo:joe@example.net, sam@example.org, $thomas@example.co.uk

After entering a suitable title (perhaps "Important message") and message ("SPAM is good!!!") the attacker can use the mail server at example.com to send mass quantities of spam. It will probably continue until the example.com admin using someone@example.com opens their email and gets a mass of spam and turns off the form. The $_REQUEST['email'] should have been filtered to not allow the newline to introduce additional headers. Even better, don't use form supplied data to generate headers at all. The sender's email address can be embedded within the message contents. In my contact form code I filter the submitted data, I check for referrer which should be my own domain (this can be faked), and I'm using sessions plus a CAPTCHA that is encrypted and passed via the session, to prevent automated access (the CAPTCHA) and to make it difficult to misuse my form. I'm curious if any W3S forum members can think of any other ways to protect form submissions.

Edited by So Called
  • Like 1
Link to comment
Share on other sites

The $_REQUEST['email'] should have been filtered to not allow the newline to introduce additional headers
i like to add one thing here ,It will be better to use whitelist approach to filter the fields.means it should check the value which should be there it should not check the value which should not be there.you know that fields only needs email address to get your application working so it is best to use regex based filtering to match exact email pattern rather than new lines or any other thing.a benifit with whitelist approach is new attacks could be invented and blacklst will be hard to maintain.
in my contact form code I filter the submitted data, I check for referrer which should be my own domain (this can be faked), and I'm using sessions plus a CAPTCHA that is encrypted and passed via the session, to prevent automated access
captcha is good for prevent bots and adding another layer of secrity but it is still vulnrable if user try to manualy mail inject on in any vulnrable script. i dont know how much refere checkig will be effective. as you already stated it can be faked. more over that any attacker can also inject mails from your own form. they dont need to alter inputs to textarea. they still can enter new line feed like eg just typing \n
Link to comment
Share on other sites

Guest So Called

I'm using regex as part of my filtering. None of the data the user supplies ends up any place but the message area. The CAPTCHA works in my favor of preventing injection because my form won't validate without the CAPTCHA filled correctly, and that depends on the integrity (or faking) of the PHP session. The correct CAPTCHA is hashed and included in the session. If the form user doesn't provide the correct answer back the form goes nowhere except try again. Without any way to insert TO headers the only place my contact form goes is to my own address, and I doubt the trouble would be worth it. In other words I've hardened the target to sufficient degree that a hacker being able to send an email to me alone isn't worth his trouble. I tried to crack the example form myself, including adding \n and it didn't work. I surmise that the <INPUT> field does not accept newline characters. That's why I changed it to a <TEXTAREA> on the attack form. In the end an attacker can always fake any data he wants. The real issue is what it gains him. If there's no gain then the target isn't worth attacking. My contact form doesn't interact with SQL so there's no place for a SQL injection, and I have it sufficiently nailed down that it's unlikely it can be compromised to use it to send email to other destinations. Of course no code is perfect. I posted this topic just to get people thinking along these lines.

Edited by So Called
Link to comment
Share on other sites

The CAPTCHA works in my favor of preventing injection because my form won't validate without the CAPTCHA filled correctly, and that depends on the integrity (or faking) of the PHP session. The correct CAPTCHA is hashed and included in the session. If the form user doesn't provide the correct answer back the form goes nowhere except try again.
yes. bu what i meant is that human can pass the capctha.only robots can't
Without any way to insert TO headers the only place my contact form goes is to my own address, and I doubt the trouble would be worth it.
hardcoded TO header can also be spoofed or attacker can use other email address to send mass emails even worse can manupulate the any headers. even message body which may break system security or trustworthiness. $_REQUEST['email'] can manupulate any headers as attacker want if it is not properly filtered.
I tried to crack the example form myself, including adding \n and it didn't work. I surmise that the <INPUT> field does not accept newline characters. That's why I changed it to a <TEXTAREA> on the attack form.
Most email server takes CRLF eg \r\n in header
I posted this topic just to get people thinking along these lines.
no doubt it is a nice topic and will be helpfull for all.
Link to comment
Share on other sites

Guest So Called

In my case the To, Subject and From lines are hard coded. Any information sent by a hacker appears only in the body of the email, which is too late to insert more headers. The biggest mistake in the example was to add any additional headers at all, or at least allowing user input to appear in that area. In other words, here's an improvement:

<html><body> <?phpif (isset($_REQUEST['email']))//if "email" is filled out, send email  {  //send email  $email = $_REQUEST['email'] ;  $subject = $_REQUEST['subject'] ;  $message = $_REQUEST['message'] ;   // at this point filter $email, $subject and $message to allow only characters you need  // apply any additional security testing you think is appropriate   $message = "You've received a reply from the site's contact form: From: $emailSubject: $subject $message";   mail("someone@example.com", "Contact Form Response", $message, "From: contactform@example.com");  // note that the only field that isn't hard coded is the message itself   echo "Thank you for using our mail form";  }else//if "email" is not filled out, display the form  {  echo "<form method='post' action='mailform.php'>  Email: <input name='email' type='text' /><br />  Subject: <input name='subject' type='text' /><br />  Message:<br />  <textarea name='message' rows='15' cols='40'>  </textarea><br />  <input type='submit' />  </form>";  }?> </body></html>

Now all the user supplied information appears only in the body of the email. This is just one way to do it and IMO not even the best way, but again I'm just offering it as an alternative example.

Link to comment
Share on other sites

Guest So Called

THanks Ing. I had not seen that chapter. It supports some of what I've been saying. I still think that giving site visitors any access to the From header is a bad practice. IMO it would be better to provide a mailto: link in the message content so that the webmaster can click that and reply to the form submitter directly.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...