preg_match()

Prevent email injection

Page 1 of 1

13 Replies - 1716 Views - Last Post: 23 September 2009 - 11:57 AM Rate Topic: -----

#1 1cookie  Icon User is offline

  • D.I.C Regular

Reputation: -5
  • View blog
  • Posts: 338
  • Joined: 19-October 06

preg_match()

Posted 21 September 2009 - 06:08 AM

hi

I'm designing a form for my website and would like to tighten the validation up a little. I want to stop a potential spammer from inserting newline characters "\r" & "\n" into the 'email' field in my form. My code looks like:


<?php
	$fname = $_REQUEST['fname'];
	$sname = $_REQUEST['sname'];

	$email = $_REQUEST['email'];
	$message = $_REQUEST['message'];

 if ( preg_match( "/[\r\n]/", $fname ) || preg_match( "/[\r\n]/", $email ) ) {

  header( "Location: error.html " );
//now quit

  }	
	
	
  if (!isset ($_REQUEST['email'] ) || empty($fname)  ) {
  
  
  ?>

<html>

<p>some html code here</p>
<form>My form</form>

</html>


  <?php
  
  }
  
 
  
  else {
  
  mail( "info@webtechnologies.me.uk", "Feedback Form Results",
	$message, "From: $fname $sname <$email>" );
  header( "Location: thankyou.html " );
  }
  //launches the thankyou page
 
?>






The code works fine for most purposes. When i put a "\n" or a "\r" into the email field though - i'm expecting the program to redirect the user to the error.html page, only, it doesn't!! :) It just happily displays the thankyou.html page? :)

help please...

Is This A Good Question/Topic? 0
  • +

Replies To: preg_match()

#2 RudiVisser  Icon User is offline

  • .. does not guess solutions
  • member icon

Reputation: 1003
  • View blog
  • Posts: 3,562
  • Joined: 05-June 09

Re: preg_match()

Posted 21 September 2009 - 06:14 AM

Do you actually mean a newline or just the two characters \ and n or \ and r, because that won't catch the latter.

Also, using PCRE for that task is overkill, you could use ereg or simply do a strpos.

function strcontains($needle, $haystack) {
   return (strpos($needle, $haystack) !== false);
}

This post has been edited by MageUK: 21 September 2009 - 06:14 AM

Was This Post Helpful? 0
  • +
  • -

#3 1cookie  Icon User is offline

  • D.I.C Regular

Reputation: -5
  • View blog
  • Posts: 338
  • Joined: 19-October 06

Re: preg_match()

Posted 21 September 2009 - 06:28 AM

View PostMageUK, on 21 Sep, 2009 - 05:14 AM, said:

Do you actually mean a newline or just the two characters \ and n or \ and r, because that won't catch the latter.

Also, using PCRE for that task is overkill, you could use ereg or simply do a strpos.

function strcontains($needle, $haystack) {
   return (strpos($needle, $haystack) !== false);
}


hi Mage

you've lost me there a little! :) I'm referring to this example.

View PostMageUK, on 21 Sep, 2009 - 05:14 AM, said:

Do you actually mean a newline or just the two characters \ and n or \ and r


I think the tutorial is referring to the two characters \ and n or \ and r. :)


How would i incorporate your example into my code, could you give me an example please? :)
Was This Post Helpful? 0
  • +
  • -

#4 RudiVisser  Icon User is offline

  • .. does not guess solutions
  • member icon

Reputation: 1003
  • View blog
  • Posts: 3,562
  • Joined: 05-June 09

Re: preg_match()

Posted 21 September 2009 - 06:36 AM

No that script is referring to actual newlines, which it would probably work fine for.

If you change the email field to a textbox and press enter in it to get a new line, you'd be redirected to the error.. It won't catch you typing \r\n in the box, they're special characters.

Anyway just do something like this:
function strcontains($needle, $haystack) {
   if(is_array($needle)) {
	  foreach($needle as $item)
		 if(strpos($item, $haystack) !== false) return true;
	  return false;
   } else
	  return (strpos($needle, $haystack) !== false);
}
$BadChars = array("\n", "\r");
if (strcontains($BadChars, $fname) || strcontains($BadChars, $email))
   header("Location: error.html");

This post has been edited by MageUK: 21 September 2009 - 06:37 AM

Was This Post Helpful? 0
  • +
  • -

#5 1cookie  Icon User is offline

  • D.I.C Regular

Reputation: -5
  • View blog
  • Posts: 338
  • Joined: 19-October 06

Re: preg_match()

Posted 21 September 2009 - 07:57 AM

View PostMageUK, on 21 Sep, 2009 - 05:36 AM, said:

No that script is referring to actual newlines, which it would probably work fine for.

If you change the email field to a textbox and press enter in it to get a new line, you'd be redirected to the error.. It won't catch you typing \r\n in the box, they're special characters.


hi Mage

I tried changing the email field to a text box but the script wont execute the header error.htm! :)


My php file now looks like:


<?php

	$fname = $_REQUEST['fname'];
	$sname = $_REQUEST['sname'];

	$email = $_REQUEST['email'];
	$message = $_REQUEST['message'];

	
	function strcontains($needle, $haystack) {
   if(is_array($needle)) {
	  foreach($needle as $item)
		 if(strpos($item, $haystack) !== false) return true;
	  return false;
   } else
	  return (strpos($needle, $haystack) !== false);
}

$BadChars = array("\n", "\r");
if (strcontains($BadChars, $fname) || strcontains($BadChars, $email))
   header("Location: error.html");

	
	
  elseif (!isset ($_REQUEST['email'] ) || empty($fname)  ) {
  
 
  ?>
  
<html>
<form>My form</form>
</html>


  <?php
  
  }
  

  
  else {
  
  mail( "info@webtechnologies.me.uk", "Feedback Form Results",
	$message, "From: $fname $sname <$email>" );
  header( "Location: thankyou.html " );
  }
  
 
?>






I run the form from a html file index5.html with inputs:


somemai@somewhere.com \n another@mail.com \r


in the email field - but the php script does not redirect me to the error page! :)
Was This Post Helpful? 0
  • +
  • -

#6 RudiVisser  Icon User is offline

  • .. does not guess solutions
  • member icon

Reputation: 1003
  • View blog
  • Posts: 3,562
  • Joined: 05-June 09

Re: preg_match()

Posted 21 September 2009 - 07:59 AM

It won't, as I've said, they're special characters, just typing the 2 characters in won't make a difference.

If you really want, to test that it works, change
$BadChars = array("\n", "\r");
to
$BadChars = array("\n", "\r", "\\r", "\\n");

This post has been edited by MageUK: 21 September 2009 - 07:59 AM

Was This Post Helpful? 0
  • +
  • -

#7 1cookie  Icon User is offline

  • D.I.C Regular

Reputation: -5
  • View blog
  • Posts: 338
  • Joined: 19-October 06

Re: preg_match()

Posted 21 September 2009 - 08:16 AM

View PostMageUK, on 21 Sep, 2009 - 06:59 AM, said:

It won't, as I've said, they're special characters, just typing the 2 characters in won't make a difference.

If you really want, to test that it works, change
$BadChars = array("\n", "\r");
to
$BadChars = array("\n", "\r", "\\r", "\\n");


hi
I make those changes and enter: some@mail.com \n another@mail.com \r, in the email field - and the script doesn't take me to the error page! :)

It happily displays the thenkyou page! :)

I'm a little confused, are the "\n" and "\r" characters supposed to create "new lines" or carriage returns in a text field? :)
Was This Post Helpful? 0
  • +
  • -

#8 1cookie  Icon User is offline

  • D.I.C Regular

Reputation: -5
  • View blog
  • Posts: 338
  • Joined: 19-October 06

Re: preg_match()

Posted 21 September 2009 - 12:55 PM

[quote name='1cookie' date='21 Sep, 2009 - 07:16 AM' post='774389']

View PostMageUK, on 21 Sep, 2009 - 06:59 AM, said:

It won't, as I've said, they're special characters, just typing the 2 characters in won't make a difference.

If you really want, to test that it works, change
$BadChars = array("\n", "\r");
to
$BadChars = array("\n", "\r", "\\r", "\\n");


hi
After struggling with both methods I'm close, with this i think...



<?php
function spamcheck($field)
  {
  //filter_var() sanitizes the e-mail
  //address using FILTER_SANITIZE_EMAIL
  $field=filter_var($field, FILTER_SANITIZE_EMAIL);

  //filter_var() validates the e-mail
  //address using FILTER_VALIDATE_EMAIL
  if(filter_var($field, FILTER_VALIDATE_EMAIL))
	{
	return TRUE;
	}
  else
	{
	return FALSE;
	}
  }

if (isset($_REQUEST['email']) && !empty($fname) )
  {//if "email" is filled out, proceed

  //check if the email address is invalid
  $mailcheck = spamcheck($_REQUEST['email']);
  if ($mailcheck==FALSE)
	{
	echo "Invalid input";
	}
  else
	{//send email
	
	$fname = $_REQUEST['fname'];
	$sname = $_REQUEST['fname'];
	$email = $_REQUEST['email'];
	$message = $_REQUEST['message'];
	
	mail( "info@webtechnologies.me.uk", "Feedback Form Results",
	$message, "From: $fname $sname <$email>" );
	echo "Thank you for using our mail form";
	}
  }
  
else
  { //if "email" is not filled out, display the form
  echo '<table border="0"><tr><td width="70" align="right">FirstName:</td><td width="250" align="left">'
  '<form name="myform" action="sendmail.php" onsubmit="return validate_form(this)" method="post">'
  '<input type="text" name="fname" size="35" /></td>'
  '</tr><tr><td width="70" align="right">Surname:</td><td width="250" align="left">'
'<input type="text" name="sname" size="35" /></td>'
'</tr><tr><td width="70" align="right">Email:</td><td width="250" align="left">'
'<input type="text" name="email" size="35" /></td>'
'</tr><tr><td width="70" align="right"></td><td width="250" align="left">Comments:<br>'
'<textarea name="message" cols="40" rows="10"></textarea></td></tr><tr>'
'<td width="70" align="left"></td><td width="250" align="left"><input type="submit" value="submit" /></td>'
'</form></tr></table></body></html>';

	  }
?>

</body>
</html>





Upon running my html file though i get: "Parse error: syntax error, unexpected T_CONSTANT_ENCAPSED_STRING, expecting ',' or ';' in C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\test\sendmail.php on line 40" :)



	$message, "From: $fname $sname <$email>" );	 //line 40




buh! :)


help please
Was This Post Helpful? 0
  • +
  • -

#9 1cookie  Icon User is offline

  • D.I.C Regular

Reputation: -5
  • View blog
  • Posts: 338
  • Joined: 19-October 06

Re: preg_match()

Posted 22 September 2009 - 07:53 AM

hi

I seem to be going round in circles with this





<?php

	$name = $_REQUEST['name'];
	$email = $_REQUEST['email'];
	$subject = $_REQUEST['subject'];
	$message = $_REQUEST['message'];



function valid_email($email) {
$pattern = '/^([a-z0-9])(([-a-z0-9._])*([a-z0-9]))*\@([a-z0-9])' .
'(([a-z0-9-])*([a-z0-9]))+' . '(\.([a-z0-9])([-a-z0-9_-])?([a-z0-9])+)+$/i';	

return (preg_match($pattern, $email));

}

if(!valid_email($email))
{	
echo "invalid email";
}
else {

echo "valid email";


}
	
	
?>





It prints "invalid email" for a valid one! :)


help please
Was This Post Helpful? 0
  • +
  • -

#10 RudiVisser  Icon User is offline

  • .. does not guess solutions
  • member icon

Reputation: 1003
  • View blog
  • Posts: 3,562
  • Joined: 05-June 09

Re: preg_match()

Posted 22 September 2009 - 07:59 AM

Use PHP's email validation through filter_var.

function valid_email($email) {
	return (!filter_var($email, FILTER_VALIDATE_EMAIL)?false:true);
}

Was This Post Helpful? 0
  • +
  • -

#11 1cookie  Icon User is offline

  • D.I.C Regular

Reputation: -5
  • View blog
  • Posts: 338
  • Joined: 19-October 06

Re: preg_match()

Posted 22 September 2009 - 08:04 AM

View PostMageUK, on 22 Sep, 2009 - 06:59 AM, said:

Use PHP's email validation through filter_var.

function valid_email($email) {
	return (!filter_var($email, FILTER_VALIDATE_EMAIL)?false:true);
}



Ive tried that Mage, My server isn't running php 5.2+ and so does'nt recognize the built-in filter functions! :)

edit: Ive even tried using ".htaccess" also, no good!

So i have to do it the hard way boo hoo! :)



Edit: If i can limit the size of the email input field somehow, would that not save me all the hassle of worrying about email injection?

This post has been edited by 1cookie: 22 September 2009 - 09:05 AM

Was This Post Helpful? 0
  • +
  • -

#12 Wimpy  Icon User is offline

  • R.I.P. ( Really Intelligent Person, right? )
  • member icon

Reputation: 159
  • View blog
  • Posts: 1,038
  • Joined: 02-May 09

Re: preg_match()

Posted 22 September 2009 - 12:11 PM

well, as long as you are using a <input>-element you should be able to use the maxlength attribute, but you should note that every form can be spoofed, meaning that a user could potentially use his own form and send the request to your processing page! :) You can though, check the length of the value in the element server-side using the strlen() function in PHP. :)

When it comes to not allowing whitespace, simply remove all whitespace in the input instead of checking for validity, even though a validity check would be a lot better:
$cleaned_value = preg_replace('/\s+/', '', $value);
or something like that! :)
Was This Post Helpful? 0
  • +
  • -

#13 1cookie  Icon User is offline

  • D.I.C Regular

Reputation: -5
  • View blog
  • Posts: 338
  • Joined: 19-October 06

Re: preg_match()

Posted 23 September 2009 - 10:26 AM

View PostWimpy, on 22 Sep, 2009 - 11:11 AM, said:

well, as long as you are using a <input>-element you should be able to use the maxlength attribute, but you should note that every form can be spoofed, meaning that a user could potentially use his own form and send the request to your processing page! :) You can though, check the length of the value in the element server-side using the strlen() function in PHP. :)

When it comes to not allowing whitespace, simply remove all whitespace in the input instead of checking for validity, even though a validity check would be a lot better:
$cleaned_value = preg_replace('/\s+/', '', $value);
or something like that! :)



Thanks Mage, Wimpey. :) I think i got a reasonably secure working form now - making use of php's preg_replace() function amongst others. That was pretty hard work! :) I should be an expert on email injection by now. :)

thanks all...
Was This Post Helpful? 0
  • +
  • -

#14 Wimpy  Icon User is offline

  • R.I.P. ( Really Intelligent Person, right? )
  • member icon

Reputation: 159
  • View blog
  • Posts: 1,038
  • Joined: 02-May 09

Re: preg_match()

Posted 23 September 2009 - 11:57 AM

Glad to hear that you became an expert on the subject! :P Happy to help! :)

View Post1cookie, on 23 Sep, 2009 - 07:26 PM, said:

Thanks Mage, Wimpey. :) I think i got a reasonably secure working form now - making use of php's preg_replace() function amongst others. That was pretty hard work! :) I should be an expert on email injection by now. :)

thanks all...

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1