Jump to content

secure message mailform


digitalecartoons

Recommended Posts

I'm trying to make my mail form secure so no malicious script can be inserted into the message text. At first I thought about using htmlentities filtering, but that would turn characters like & < and > into their html entity equivalent in the arriving message body text when set to text/plain.

 

I could let it send as text/html, but that would turn everything back into the bad script, making it insecure again.

 

I want to have text sent filtered from dangerious html tags, as a text/plain mail, but when receiving it as text/plain mail displaying as there original characters again. How can I do that?

 

I no it can be done because when I sent myself a html mail with this line:

<script>for(var i = 0; i < 2; i++) { alert("Hi!"); }</script>

I receive it as html mail like that (without it executing the script) and when I switch the display to plain text I get the same line without any html entity codes. So somehow the html tags in this line are not seen as html tags, both when displaying as text/html as text/plain.

Link to comment
Share on other sites

what about this, to filter the html..

you could replace "good tags" with [] then filter then replace back

ie

<B> replace with [b]
filter
[b] replace with <B>

 

$html= preg_replace('%<(/?B)>%sim', '[$1]', $html);

 

html = "<html>
<body>
test
<script>";
$html = preg_replace('%<[a-zA-Z/][^>]*>%sim', '', $html);

 

$html= preg_replace('%\[(/B)\]%sim', '<$1>', $html);

Link to comment
Share on other sites

Someone told me that I'm in no danger of hackers inserting malicious scripts into the message text, as long as if I close the headers properly by inserting an empty line after it? Is that correct? Inserting an empty line after the header is letting the header know it has ended, he says. So any script in the message text after having inserted a last empty line after the headers isn't regarded as potentially bad script tags, he says.

 

Is that true? If so, I wouldn't have any need for something like htmlentities of tag filtering.

 

Link to comment
Share on other sites

thats not really hackers but spammers, the header should be ofcourse filtered, as the spammer could inject a new "from: " header but adding the "\\r\\n" will not protect you..

 

bascially the

email strict fully valid email

name & subject must be A-Z0-9

the body your need to filter the above post and probably remove (%0A)

Link to comment
Share on other sites

O right, well I guess I've got hackers blocked by checking for a session variable so my php script can't be accessed directly. But now about spammers. I've got my From and Email field already protected by using regular expressions to check for a valid name and email address like you said. It's only just the Message field I'm still worried about. Just how secure is my mail script? Or the message part anyway?

 

<?php

/* Email settings, doing some basic filtering */
/* Used by Flash form so utf8 decode neccessary for allowing international (accented) characters */
$to = "info@my_email_address.nl";
$subject = "Request for information";
$naam = stripslashes(utf8_decode($_POST["naam"]));
$email = stripslashes(utf8_decode($_POST["email"]));
$bericht = stripslashes(utf8_decode($_POST["bericht"]));


/* Checking for a proper name, including accented characters, apostrophe, space and hyphen */
if (!preg_match('~^[a-zÀ-ÿ][\'a-zÀ-ÿ \-]*$~i', $naam)) {
$naam = "error";
echo "&naam=error&";
} else {
echo "&naam=correct&";
}

/* Checking for properly formed email address*/
if (!preg_match('~^[a-z0-9][a-z0-9_.\-]*@([a-z0-9]+\.)*[a-z0-9][a-z0-9\-]+\.([a-z]{2,6})$~i', $email)) {
$email = "error";
echo "&email=error&";
} else {
echo "&email=correct&";
}

/* Has a message been filled in? */
if (!$bericht) {
$bericht = "error";
echo "&bericht=error&";
} else {
echo "&bericht=correct&";
}

/* If so, send it as plain text mail */
if ($naam != "error" && $email != "error" && $bericht != "error") {

$message = "Naam:\r\n".$naam."\r\n\r\n";
$message .= "Emailadres:\r\n".$email."\r\n\r\n";
$message .= "Bericht:\r\n".$bericht."\r\n";

$headers = "MIME-Version: 1.0\r\n";  
$headers .= "Content-type: text/plain; charset=iso-8859-1\r\n";
$headers .= "From: ".mb_encode_mimeheader($naam, "iso-8859-1", "Q")." <".$email.">\r\n";  

mail($to, $subject, $message, $headers);

}
?>

 

 

Link to comment
Share on other sites

1. if you dont want any html then use trim()

2. if you do want them then use this...

 

###
#  BB Code, allow html style
#  safely, and via BB Code
#
$bb_codes = array(
   # bold
  '[b]' => '<span style="font-weight:bold">',
  '[/b]' => '</span>',
    # italic
  '[i]' => '<span style="font-style:italic">',
  '[/i]' => '</span>',
    # underline
  '[u]' => '<span style="text-decoration:underline">',
  '[/u]' => '</span>',
    # bold
  '[b]' => '<span style="font-weight:bold">',
  '[/b]' => '</span>',
    # italic
  '[i]' => '<span style="font-style:italic">',
  '[/i]' => '</span>',
    # underline
  '[u]' => '<span style="text-decoration:underline">',
  '[/u]' => '</span>',
    # added
'[img]' => '<img src="',
'[/img]' => '" border=0>',
'[img]' => '<img src="',
'[/img]' => '">',
'[url]' => '<a href="',
'[/url]' => '">Link</a>',
'[url]' => '<a href="',
'[/url]' => '">Link</a>',
'
[center]' => '<div align=center>',
'[/center]
' => '</div>',
'[mail]' => '<a href=mailto:"',
'[/mail]' => '">Email</a>',
'[color=Red]' => '<font color=red>',
'[/color]' => '</font>',
'[color=Blue]' => '<font color=blue>',
'[/color]' => '</font>',
'[color=Purple]' => '<font color=purple>',
'[/color]' => '</font>',
'[color=Yellow]' => '<font color=yellow>',
'[/color]' => '</font>',
'[color=Default]' => '<font color=black>',
'[/color]' => '</font>',
'[color=Green]' => '<font color=green>',
'[/color]' => '</font>',
'[quote]' => '<center><div id="quote" style="width:350;overflow:auto">',
'[/quote]' => '</div></center>',
    # smilies
  ':]' => '<img src="">',
  ':[' => '<img src="">',
  ':l' => '<img src="">',
  ';]' => '<img src="">',
  '>:]' => '<img src="">',
  '' => '<img src="">',
  ':tounge:' => '<img src="">',
  ':mad:' => '<img src="">'
);
###
#  Bbcode/text replace function
# 
function bbcodes($t) 
{
$search = array_keys($GLOBALS['bb_codes']);
$t = str_ireplace($search, $GLOBALS['bb_codes'], $t);
return $t;
}

Link to comment
Share on other sites

%0A stands for Linefeed?

 

With html forms there was no need for utf8 decode, but I noticed that with Flash forms names like René got converted to something like Ren%8. utf8 decode fixed that so it became René again.

 

With the php script being protected through session variables, name/email being regexed and such a strict formatting of the headers en message part, the only remaining thing I'm curious about is how spam proof the message field is now.

Link to comment
Share on other sites

1. if you dont want any html then use trim()

 

trim() does not remove HTML, it removes extra spaces!

http://us.php.net/trim

 

Read this page on PHP&HTML:

http://us.php.net/manual/en/faq.html.php

 

strip_tags() removes HTML (and PHP)

http://us2.php.net/strip_tags

 

You can also look into PEAR's HTML Safe, which I use and like a lot:

http://pear.php.net/package/HTML_Safe

Link to comment
Share on other sites

Already tried strip_tags but that would sometimes delete more text than it should

mytest1<mytest2<mytest3

 

would result in

mytest1

 

Then it would be better to use htmlentities but that would convert certain characters to its code which I sometime wouldn't want like in

"do you know a<b & d>d?"

 

But perhaps, the way my mailscript is set up, such a thing isn't even necessary? Can it somehow be  used for spamming? Or is it pretty safe without using something like htmlentities?

Link to comment
Share on other sites

if someone enter something like this if the from field

ME@domain.com%0ACc:victim@hotmail.com

the message Cc to victim@hotmail.com as well

 

if you wish to keep some tags you could use strip_tags and exclude some ie

$html = strip_tags($html, '<b><i><u>');

 

i'll admit i always forgot that function, (too much playing with regex)

Link to comment
Share on other sites

Tried that but that's not possible:

 

1. The name field has a regex which only allows letters, apostrophe, hypen and space

2. The email field has a regex too which wouldn't accept a line like ME@domain.com%0ACc:victim@hotmail.com (regex has a very strict format).

 

Your line is not accepted by the regex anyway. So I guess that part is pretty safe.

 

So how about the message field? Is there something vulnerable there? Some line which would do something similar? Even when not using htmlentities/strip_tags?

Link to comment
Share on other sites

you can also use it at the start of the body/message (header), but if the %0A is filtered then you should be fine.

 

 

it looks fine, but i am unsure when it comes to unicode and protection

 

add this

 

$email = preg_replace('/%0A/', '', $email);

before sending

 

will kill a few attemps at header injection

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.