By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
439,978 Members | 1,373 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 439,978 IT Pros & Developers. It's quick & easy.

Email injection on a contact form

P: n/a
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 containsInjectionAttempt($input) {
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 containsInjectionAttempt function

// Check for injection attempts
if (containsInjectionAttempt($_POST['userName']) ||
containsInjectionAttempt($_POST['address']) ||
containsInjectionAttempt($_POST['address2'])
|| containsInjectionAttempt($_POST['city']) ||
containsInjectionAttempt($_POST['zip']) ||
containsInjectionAttempt($_POST['phone'])
|| containsInjectionAttempt($_POST['email'])) {
// There has been an injection attempt
while (list($key, $value) = each($_POST)) {
$message .= $key.": ".$value."\n";
} // end of while
mail ("me@test.com", "Injection attempt on Web Site", $message,
"From: in**@website.com");
$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

Aug 6 '06 #1
Share this Question
Share on Google+
8 Replies


P: n/a
st******@integrastrategic.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
--
http://www.petezilla.co.uk
Aug 6 '06 #2

P: n/a
Peter Chant <pe**@petezilla.co.ukwrote:
st******@integrastrategic.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
Aug 6 '06 #3

P: n/a
st******@integrastrategic.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 containsInjectionAttempt($input) {
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 containsInjectionAttempt function

// Check for injection attempts
if (containsInjectionAttempt($_POST['userName']) ||
containsInjectionAttempt($_POST['address']) ||
containsInjectionAttempt($_POST['address2'])
|| containsInjectionAttempt($_POST['city']) ||
containsInjectionAttempt($_POST['zip']) ||
containsInjectionAttempt($_POST['phone'])
|| containsInjectionAttempt($_POST['email'])) {
// There has been an injection attempt
while (list($key, $value) = each($_POST)) {
$message .= $key.": ".$value."\n";
} // end of while
mail ("me@test.com", "Injection attempt on Web Site", $message,
"From: in**@website.com");
$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
Aug 6 '06 #4

P: n/a
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: <an*******@arthur.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: <20************************@arthur.website.com>
To: in**@website.com
Subject: Inquiry from website Web site:
From: to@arthur.website.com
Content-Transfer-Encoding: 8bit

Content-Type: text/plain

Subject: for the content of


in violation of applicable laws.



c38c84c3c20b7d288cf34180343fc74f

..

<eg***********@website.com>

userName: to

Content-Transfer-Encoding: 8bit

Content-Type: text/plain

Subject: for the content of

bcc: bu*******@aol.com

in violation of applicable laws.

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

The email message also contained this error:

Hi. This is the qmail-send program at arthur.integrastrategic.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.

<bu*******@aol.com>:
64.12.138.152 failed after I sent the message.
Remote host said: 554-: (RLY:CS4)
http://postmaster.info.aol.com/errors/554rlycs4.html
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 <in**@website.com>";
} // end of else
$message = stripslashes($message);
mail ("in**@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:
st******@integrastrategic.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 containsInjectionAttempt($input) {
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 containsInjectionAttempt function

// Check for injection attempts
if (containsInjectionAttempt($_POST['userName']) ||
containsInjectionAttempt($_POST['address']) ||
containsInjectionAttempt($_POST['address2'])
|| containsInjectionAttempt($_POST['city']) ||
containsInjectionAttempt($_POST['zip']) ||
containsInjectionAttempt($_POST['phone'])
|| containsInjectionAttempt($_POST['email'])) {
// There has been an injection attempt
while (list($key, $value) = each($_POST)) {
$message .= $key.": ".$value."\n";
} // end of while
mail ("me@test.com", "Injection attempt on Web Site", $message,
"From: in**@website.com");
$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
Aug 7 '06 #5

P: n/a
st******@integrastrategic.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 <in**@website.com>";
} // end of else
$message = stripslashes($message);
mail ("in**@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_data($str)
{
return substr(preg_replace('/[^\w .@+\-]/', '', $str), 0, 50);
}

Then you can do

$from = clean_header_data($_POST['userName']) . ' <' .
clean_header_data($_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
Aug 7 '06 #6

P: n/a
st******@integrastrategic.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
Aug 7 '06 #7

P: n/a
Steven Musumeche <st*************@yahoo.comwrote:
st******@integrastrategic.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
Aug 7 '06 #8

P: n/a
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_data wouldn't stop the
injection since it is going through the other form element.

Thanks again!

Sincerely,
Scott

Miguel Cruz wrote:
Steven Musumeche <st*************@yahoo.comwrote:
st******@integrastrategic.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
Aug 7 '06 #9

This discussion thread is closed

Replies have been disabled for this discussion.