The Web Design Group

... Making the Web accessible to all.

Welcome Guest ( Log In | Register )

 
Reply to this topicStart new topic
> PHP Security, What are the risks?
michelle
post May 3 2007, 01:29 AM
Post #1


Newbie
*

Group: Members
Posts: 12
Joined: 19-April 07
From: Australia
Member No.: 2,569



Hi

I have put a form on a website I have built for my dad's business that allows potential customers to ask for a quote, it is much like a 'contact us' layout, it is here: http://www.darcyengineering.com.au/RequestQuote.html

I have used a php script for the form and was wondering how vulnerable I have made myself (and the information that users submit through this form) to third party monitoring? I have heard that some programs search for these sorts of things and use the email addresses to send spam to?

If I have left myself with a security issue, what is the best (free preferably!) solution?

I am happy to learn a little about php code to do this, I just need a little guidance!

For those interested, here is the php coding - I used www.thesitewizard.com to make it as well as secuirty notes from another site - I can go through my history and find it is anyone is interested:

CODE
<?

  $name = strip_tags(substr($_REQUEST['name'],0,32));
  $company = strip_tags(substr($_REQUEST['company'],0,32));
  $email = strip_tags(substr($_REQUEST['email'],0,32));
  $phone = strip_tags(substr($_REQUEST['phone'],0,32));
  $mobile = strip_tags(substr($_REQUEST['mobile'],0,32));
  $description = strip_tags(substr($_REQUEST['description'],0,32));

  mail( "info@darcyengineering.com.au", "Quote Request",
"Name: $name\nCompany:$company\nEmail: $email\nPhone: $phone\nMobile: $mobile\nJob Description: $description",
"From: $email");
  header( "Location: http://www.darcyengineering.com.au/QuoteRequestReceived.html" );
?>


Thanks

Michelle
User is offlinePM
Go to the top of the page
Toggle Multi-post QuotingQuote Post
Brian Chandler
post May 3 2007, 04:10 AM
Post #2


Jocular coder
********

Group: Members
Posts: 2,460
Joined: 31-August 06
Member No.: 43



QUOTE(michelle @ May 3 2007, 03:29 PM) *

For those interested, here is the php coding - I used www.thesitewizard.com to make it as well as secuirty notes from another site - I can go through my history and find it is anyone is interested:

CODE
<?

  $name = strip_tags(substr($_REQUEST['name'],0,32));
  $company = strip_tags(substr($_REQUEST['company'],0,32));
  $email = strip_tags(substr($_REQUEST['email'],0,32));
  $phone = strip_tags(substr($_REQUEST['phone'],0,32));
  $mobile = strip_tags(substr($_REQUEST['mobile'],0,32));
  $description = strip_tags(substr($_REQUEST['description'],0,32));

  mail( "info@darcyengineering.com.au", "Quote Request",
"Name: $name\nCompany:$company\nEmail: $email\nPhone: $phone\nMobile: $mobile\nJob Description: $description",
"From: $email");
  header( "Location: http://www.darcyengineering.com.au/QuoteRequestReceived.html" );
?>




Hmm. I don't really understand the point of strip_tags() here. It removes html and php tags, which matters for text you are going to echo to a web page, but not (AFAICS) for text you are going to send in an email.

Equally, I don't understand *at all* the point of truncating the bits to 32 characters, particularly without telling the person sending the message.

But what you do have to worry about for an email form is someone using it as an email relay. Is it possible to send my message "Make your ears bigger with Briagra!" to an arbitrary mail address, using this form. It looks as though it is:

Put the spam message in the "description" field, and in the "From" field put
'me@mydomain.org\nbcc:victim@spam.address.net'

This will add the "From: " header, but also a "bcc: " header, and send a blind copy to the spam victim. So Big Problem.

With text going anywhere near an email you need to worry not about html tags (or php injection), but about newline characters. Here's a relevant fragment from my mail handler:

CODE

       // check if email OR name includes suspicious newlines
if (ereg("[\n\r]", $email.$name))
{       $text .= "\n***Suspicious email***\n$reply\n";
        $reply = "";
        $susreply = TRUE;
}

if ($reply && $name)            // may need to encode name
{       $reply = hdrutf8($name). " <" . $reply . ">";
}

$subj=$m_subject[$lang];
if ($_POST['subject'])
{       if (ereg("[\n\r]", $_POST['subject']))  // includes suspicious newlines
                $text .= "\n***Suspicious subject***\n" . $_POST['subject'] . "\n";
        else
                $subj = hdrutf8($_POST['subject']);
}



I just seem to look for \n or \r in the subject (since I allow the subject to be entered: if you have a fixed subject, it's simpler, and safer), and the name and email (which I put together as

"Brian Chandler" <brian@mydomain.xyz>

(and I might have Japanese text, so I have to use a function to encode the headers - that's the UTF8 stuff that you probably don't need to worry about).

Hope this helps - of course if anyone can point out a hole in my code I'd be grateful.

The second problem you have to worry about now is automated form submissions just sending you spam. I get 100s a day, and am just in the process of putting some human-checks in. Of course if I hadn't called my contact form contact.php it might have helped.... wacko.gif wink.gif sleep.gif
User is offlinePM
Go to the top of the page
Toggle Multi-post QuotingQuote Post
michelle
post May 3 2007, 08:06 PM
Post #3


Newbie
*

Group: Members
Posts: 12
Joined: 19-April 07
From: Australia
Member No.: 2,569



Hi Brian

Thanks for your help.

I wasn't too sure about all of that strip tags stuff, I got it from this website:
http://www-128.ibm.com/developerworks/libr...rypt/index.html

I have now updated my code (to include checking so that I don't get blank forms sent to me:

CODE
<?
  $name = $_REQUEST['name'];
  $company = $_REQUEST['company'];
  $email = $_REQUEST['email'];
  $phone = $_REQUEST['phone'];
  $mobile = $_REQUEST['mobile'];
  $description = $_REQUEST['description'];

if (!isset($_REQUEST['email'])) {
    header( "Location: http://www.darcyengineering.com.au/RequestQuote.html" );
  }

elseif (empty($email) || empty($description)) {
    header( "Location: http://www.darcyengineering.com.au/error.html" );
  }
if (ereg("[\n\r]", $email.$name))
{    header( "Location: http://www.darcyengineering.com.au/error.html" );
  }
  else {
   mail( "info@darcyengineering.com.au", "Quote Request",
"Name: $name\nCompany:$company\nEmail: $email\nPhone: $phone\nMobile: $mobile\nJob Description: $description",
"From: $email");
  header( "Location: http://www.darcyengineering.com.au/QuoteRequestReceived.html" );
  }

?>


As you can see I have put in your

CODE
if (ereg("[\n\r]", $email.$name))


But was trying to just redirect that to my error page because I didn't really understand what you had done - way above my league!

It doesn't seem to work for me though, I have been testing the form and entering my email address as: info@darcyengineering.com.au\nbcc:mypersonalemail@hotmail.com

The quote request came through to the work email, but so far not to my personal address, also it displayed the 'Thankyou' page instead of my error page.

I also tried the following with it:
CODE
elseif (ereg("[\n\r]", $email.$name))

and
CODE
if (ereg("[\n\r]", $email))

and
CODE
elseif (ereg("[\n\r]", $email.$name))


still no luck!

Any thoughts?

Thanks

Michelle
User is offlinePM
Go to the top of the page
Toggle Multi-post QuotingQuote Post
michelle
post May 3 2007, 10:53 PM
Post #4


Newbie
*

Group: Members
Posts: 12
Joined: 19-April 07
From: Australia
Member No.: 2,569



Hi

I just thought that I would post this in case anyone else is having any trouble and also for some feedback if possible on what I have done.

I used a guide on: http://www.phpbuilder.com/columns/ian_gilfillan20060412.php3 to create the following for my form to try and make it a little more secure:

CODE
<?
  $name = $_REQUEST['name'];
  $company = $_REQUEST['company'];
  $email = $_REQUEST['email'];
  $phone = $_REQUEST['phone'];
  $mobile = $_REQUEST['mobile'];
  $description = $_REQUEST['description'];

function is_valid_email($email) {
  return preg_match('#^[a-z0-9.!\#$%&\'*+-/=?^_`{|}~]+@([0-9.]+|([^\s]+\.+[a-z]{2,6}))$#si', $email);
}

function contains_bad_str($str_to_test) {
  $bad_strings = array(
                "content-type:"
                ,"mime-version:"
                ,"multipart/mixed"
        ,"Content-Transfer-Encoding:"
                ,"bcc:"
        ,"cc:"
        ,"to:"
  );
  
  foreach($bad_strings as $bad_string) {
    if(eregi($bad_string, strtolower($str_to_test))) {
header( "Location: http://www.darcyengineering.com.au/error.html" );      
      exit;
    }
  }
}

function contains_newlines($str_to_test) {
   if(preg_match("/(%0A|%0D|\\n+|\\r+)/i", $str_to_test) != 0) {
header( "Location: http://www.darcyengineering.com.au/error.html" );    
     exit;
   }
}

if (!is_valid_email($email)) {
  header( "Location: http://www.darcyengineering.com.au/error.html" );
  exit;
}

contains_bad_str($email);
contains_bad_str($subject);
contains_bad_str(body);

contains_newlines($email);
contains_newlines($subject);


if (!isset($_REQUEST['email'])) {
    header( "Location: http://www.darcyengineering.com.au/RequestQuote.html" );
  }

if (empty($email)) {
    header( "Location: http://www.darcyengineering.com.au/error.html" );
  }
if (empty($description)) {
    header( "Location: http://www.darcyengineering.com.au/error.html" );
  }
else {
   mail( "info@darcyengineering.com.au", "Quote Request",
"Name: $name\nCompany:$company\nEmail: $email\nPhone: $phone\nMobile: $mobile\nJob Description: $description",
"From: $email");
  header( "Location: http://www.darcyengineering.com.au/QuoteRequestReceived.html" );
  }

?>


So far, so good, I have tested it as much as possible and it seems to be working smile.gif

Michelle
User is offlinePM
Go to the top of the page
Toggle Multi-post QuotingQuote Post
Brian Chandler
post May 4 2007, 12:29 AM
Post #5


Jocular coder
********

Group: Members
Posts: 2,460
Joined: 31-August 06
Member No.: 43



QUOTE
As you can see I have put in your

CODE
if (ereg("[\n\r]", $email.$name))


But was trying to just redirect that to my error page because I didn't really understand what you had done - way above my league!

It doesn't seem to work for me though, I have been testing the form and entering my email address as: info@darcyengineering.com.au\nbcc:mypersonalemail@hotmail.com


Sorry, the \n in the middle of that string really means "newline". You can't enter this on your standard form, because it (presumably) uses a text box for the email address. You need to make a test form in which the <input> element for the email address is a textarea, then you type

info@darcyengineering.com.au
bcc:mypersonalemail@hotmail.com

into the text area, and lo and behold the bcc: header appears in the email.

I think. This whole area is fraught with complications, and unfortunately the web is awash with slight and gross misunderstandings (possibly including mine). Notoriously, any function you find called is_valid_email() *never* gets it exactly right, typically rejecting lots of genuine addresses.

I think you need to be a bit more subtle than sending customers to an "Error" page if your email tester smells a rat - if the address is suspect, just don't send a confirmation email, but send yourself a copy anyway. I get many "suspect" email addresses, where the person simply inadvertently put a space in, but then I also get obvious misspellings of the domain name and so on.

Incidentally, not griping, but here's an obvious error in one of the functions you have found:

QUOTE
function contains_bad_str($str_to_test) {
$bad_strings = array(
"content-type:"
,"mime-version:"
,"multipart/mixed"
,"Content-Transfer-Encoding:"
,"bcc:"
,"cc:"
,"to:"
);

foreach($bad_strings as $bad_string) {
if(eregi($bad_string, strtolower($str_to_test))) {
header( "Location: http://www.darcyengineering.com.au/error.html" );
exit;
}
}
}


The person who wrote the function originally carefully converted the string being tested to lowercase; then checking against lowercase versions of the naughty strings will find them, however cases in the original. But then someone less careful came along and added in "Content-Transfer-Encoding", which will never be found by comparing with a lowercase version. This needs to be "content-transfer-encoding".
User is offlinePM
Go to the top of the page
Toggle Multi-post QuotingQuote Post

Reply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 



- Lo-Fi Version Time is now: 29th March 2024 - 06:04 PM