digitalecartoons Posted August 23, 2007 Share Posted August 23, 2007 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. Quote Link to comment Share on other sites More sharing options...
MadTechie Posted August 23, 2007 Share Posted August 23, 2007 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); Quote Link to comment Share on other sites More sharing options...
digitalecartoons Posted August 23, 2007 Author Share Posted August 23, 2007 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. Quote Link to comment Share on other sites More sharing options...
MadTechie Posted August 23, 2007 Share Posted August 23, 2007 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) Quote Link to comment Share on other sites More sharing options...
MadTechie Posted August 23, 2007 Share Posted August 23, 2007 remember you have different types of protections 1. spammers 2. what the contents has (ie script) Quote Link to comment Share on other sites More sharing options...
digitalecartoons Posted August 23, 2007 Author Share Posted August 23, 2007 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); } ?> Quote Link to comment Share on other sites More sharing options...
xyn Posted August 23, 2007 Share Posted August 23, 2007 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; } Quote Link to comment Share on other sites More sharing options...
MadTechie Posted August 23, 2007 Share Posted August 23, 2007 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 Quote Link to comment Share on other sites More sharing options...
digitalecartoons Posted August 23, 2007 Author Share Posted August 23, 2007 %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. Quote Link to comment Share on other sites More sharing options...
Jessica Posted August 23, 2007 Share Posted August 23, 2007 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 Quote Link to comment Share on other sites More sharing options...
xyn Posted August 23, 2007 Share Posted August 23, 2007 sorry, i meant strip_tags() Quote Link to comment Share on other sites More sharing options...
digitalecartoons Posted August 23, 2007 Author Share Posted August 23, 2007 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? Quote Link to comment Share on other sites More sharing options...
MadTechie Posted August 23, 2007 Share Posted August 23, 2007 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) Quote Link to comment Share on other sites More sharing options...
digitalecartoons Posted August 23, 2007 Author Share Posted August 23, 2007 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? Quote Link to comment Share on other sites More sharing options...
MadTechie Posted August 23, 2007 Share Posted August 23, 2007 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 Quote Link to comment Share on other sites More sharing options...
digitalecartoons Posted August 23, 2007 Author Share Posted August 23, 2007 But aren't my two regexes not allowing linefeeds already? Or do you mean that when I start the message text input with a linefeed (%0A = linefeed?) they still can input one of these codes? Quote Link to comment Share on other sites More sharing options...
MadTechie Posted August 23, 2007 Share Posted August 23, 2007 thats the part i am unsure of.. the use of the unicode has made it harder to work out if it will filter, best thing to do it try it Quote Link to comment Share on other sites More sharing options...
digitalecartoons Posted August 23, 2007 Author Share Posted August 23, 2007 with unicode you mean the utf8_decode I use to have the Flash Post values like René converted from Ren%8 back to René again? Someone just told me that rawurldecode() works just as well. Wouldn't convert it to utf8 temperarily Quote Link to comment Share on other sites More sharing options...
digitalecartoons Posted August 23, 2007 Author Share Posted August 23, 2007 which is better for converting Flash $POST values to the correct characters, utf8_decode or raworldecode()?. I'm sending my mails as iso-8859-1 so even if utf8_decode does the job, making it also utf8 that way and then sending it as iso-8859-1 again would be strange? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.