469,327 Members | 1,280 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,327 developers. It's quick & easy.

preg_match to detect \r\n - doesn't work

I am trying to implement email injection protection by looking for \r
and/or \n in the name, subject, or email address fields from my contact form

The first script, contact_us.php, contains a form with text fields for
name, subject, and emailaddr (the sender's email address) The message
(body of the email) is a textarea.

I post the form to send_the_email_contact.php where I have the following
test:

if(preg_match('`[\r\n]`',$_POST['subject']))
{
exit ('injection attempt ');
}

To test this, when I fill in the form, I type "This is the subject\r\n"
in the subject field.

When I click on submit and enter send_the_email_contact.php it does not
catch the \r\n. I have checked and preg_match returns a 0.

Why doesn't this test work?

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

To make it even simpler, I have created a test script with this (inside
an html body):

<form id=form1 method=POST action="<?= $_SERVER['PHP_SELF'] ?>">
<input type=text name=subject value=<?= stripslashes($_POST['subject']) ?>>
<input type=submit name=send value="Send Mail">
</form>

<?
if ($_POST['send'] == 'Send Mail')
{
echo "subject = {$_POST['subject']}<br>";
echo "subject_match = " . preg_match("/[\r\n]/", $_POST['subject']);
}
?>

If I enter "subject\r\n" in the text field and click "Send Mail" the
output is:

subject = subject\\r\\n
subject_match = 0

...... I don't get it?! Shouldn't that be a match?

--
*****************************
Chuck Anderson • Boulder, CO
http://www.CycleTourist.com
*****************************
Jan 12 '07 #1
7 19079
Rik
Chuck Anderson wrote:
If I enter "subject\r\n" in the text field and click "Send Mail" the
output is:

subject = subject\\r\\n
subject_match = 0

..... I don't get it?! Shouldn't that be a match?
The string '\r\n' != "\r\n"....
--
Rik Wasmus
Jan 12 '07 #2
Rik wrote:
Chuck Anderson wrote:
>If I enter "subject\r\n" in the text field and click "Send Mail" the
output is:

subject = subject\\r\\n
subject_match = 0

..... I don't get it?! Shouldn't that be a match?

The string '\r\n' != "\r\n"....
Okay, ... ... but I don't follow you. How does that apply?

Isn't that how someone would inject extra headers - by entering
\r\nbcc:.... (for instance)?

How do I detect that?

--
*****************************
Chuck Anderson Boulder, CO
http://www.CycleTourist.com
*****************************
Jan 12 '07 #3
Rik
Chuck Anderson wrote:
Rik wrote:
>Chuck Anderson wrote:
>>If I enter "subject\r\n" in the text field and click "Send Mail" the
output is:

subject = subject\\r\\n
subject_match = 0

..... I don't get it?! Shouldn't that be a match?

The string '\r\n' != "\r\n"....

Okay, ... ... but I don't follow you. How does that apply?

Isn't that how someone would inject extra headers - by entering
\r\nbcc:.... (for instance)?

How do I detect that?
They are not typing \r\n in that case. The \r and \n are a carriage
return/line feed characters. You probably cannot test this in your form, as
in a normal text input you cannot enter these characters (in a textarea you
can BTW). They can send POST data to your server without using the form
though, which is how they're able to send this newline characters.

To test this, you can either go through a lot of trouble trying to post
this to your script, but I'd go for the easy approach, make a string with a
newline in it and test this directly:

$string = "foo\r\nbar";
//or
$string = 'foo
bar';

And then check wether this string passes or not. It's not worth your effort
to mimique an evil post :-)
--
Rik Wasmus
Jan 12 '07 #4
Rik wrote:
Chuck Anderson wrote:
>Rik wrote:
>>Chuck Anderson wrote:
If I enter "subject\r\n" in the text field and click "Send Mail" the
output is:

subject = subject\\r\\n
subject_match = 0

..... I don't get it?! Shouldn't that be a match?
The string '\r\n' != "\r\n"....

Okay, ... ... but I don't follow you. How does that apply?

Isn't that how someone would inject extra headers - by entering
\r\nbcc:.... (for instance)?

How do I detect that?

They are not typing \r\n in that case. The \r and \n are a carriage
return/line feed characters. You probably cannot test this in your form, as
in a normal text input you cannot enter these characters (in a textarea you
can BTW). They can send POST data to your server without using the form
though, which is how they're able to send this newline characters.

To test this, you can either go through a lot of trouble trying to post
this to your script, but I'd go for the easy approach, make a string with a
newline in it and test this directly:

$string = "foo\r\nbar";
//or
$string = 'foo
bar';

And then check wether this string passes or not. It's not worth your effort
to mimique an evil post :-)
Okay, thanks. I get it now. What baffled me was just that. If I tested
by using:
$subject = "This is the Subject\r\n";
Then preg_match('`[\r\n]`',$_POST['subject']) matched. If it was POSTed
from a text field in a form it would not.

The host I'm with actually uses Apache mod_security to disallow the
string cc: to appear in *any* POST variable. But I want to make sure my
scripts are secure regardless of that. (I also think that's a bit of
annoying overkill.)

Thanks for shedding some light on that \r\n thing for me.

(I'm going to start another thread, but what got me going on this is
that someone has started using my contact form to send spam to me - and
me alone. I am tracking the usage of my script closely and I can see
that they are not even trying to use it as an open emailer. But still,
..... it's a bit annoying.)

--
*****************************
Chuck Anderson Boulder, CO
http://www.CycleTourist.com
*****************************
Jan 12 '07 #5
Chuck Anderson wrote:
<snip>
I post the form to send_the_email_contact.php where I have the following
test:

if(preg_match('`[\r\n]`',$_POST['subject']))
{
exit ('injection attempt ');

}
<snip>

You don't necessarily have to stop processing when validating mail
headers. You can easily strip out any CRLFs

<?php
$safeHeader = str_replace(array("\r","\n"), '', $_POST['subject']);
// strips out \r and \n, leaving the rest intact
?>

Curtis

Jan 13 '07 #6
Rik
Curtis wrote:
Chuck Anderson wrote:
<snip>
>I post the form to send_the_email_contact.php where I have the
following test:

if(preg_match('`[\r\n]`',$_POST['subject']))
{
exit ('injection attempt ');

}
<snip>

You don't necessarily have to stop processing when validating mail
headers. You can easily strip out any CRLFs
You don't HAVE to. However, when something that will end up in a header
contains a CRLF when it shouldn't, I'd opt for not sending the mail at all.
It shouldn't be possible, so either there's something wrong with my code or
someone has sent faulty and potentially harmfull information. Either way,
the mail should not be sent.
--
Rik Wasmus
Jan 13 '07 #7
True enough, I guess if anyone's using your script and sending CRLFs,
they probably don't have any intention of sending anything of value,
lol.

Anyway, in case anyone wants to check for CRLF without regex, it's not
too hard:

<?php
if ( strpos($header, "\r") !== false || strpos($header, "\n") !==
false ) {
// mail header injection attempt
}
?>

On Jan 13, 5:56 am, "Rik" <luiheidsgoe...@hotmail.comwrote:
Curtis wrote:
Chuck Anderson wrote:
<snip>
I post the form to send_the_email_contact.php where I have the
following test:
if(preg_match('`[\r\n]`',$_POST['subject']))
{
exit ('injection attempt ');
}
<snip>
You don't necessarily have to stop processing when validating mail
headers. You can easily strip out any CRLFsYou don't HAVE to. However, when something that will end up in a header
contains a CRLF when it shouldn't, I'd opt for not sending the mail at all.
It shouldn't be possible, so either there's something wrong with my code or
someone has sent faulty and potentially harmfull information. Either way,
the mail should not be sent.
--
Rik Wasmus
Jan 14 '07 #8

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

10 posts views Thread by aaron | last post: by
6 posts views Thread by Einar ?rn | last post: by
2 posts views Thread by splodge | last post: by
6 posts views Thread by mantrid | last post: by
4 posts views Thread by cainwebdesign | last post: by
3 posts views Thread by fienen | last post: by
3 posts views Thread by Sam Waller | last post: by
3 posts views Thread by Henri | last post: by
13 posts views Thread by chadsspameateremail | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by suresh191 | last post: by
reply views Thread by Purva khokhar | last post: by
reply views Thread by haryvincent176 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.