PHPMailer Form Help - php

Is there any better way to stop spam coming through on my phpmailer script?
Also how would I go about adding formatting to this so its more readable when it gets sent through to email e.g. break lines
I hope my php syntax is correct - as i do not understand PHP.
<?php
# bool has_injection (String $var, [String $var, ...])
function has_injection () {
$values = func_get_args();
for ($i=0, $count=func_num_args(); $i<$count; $i++) {
if ( stristr($values[$i], "%0A") || stristr($values[$i], "%0D") || stristr($values[$i], "\\r") || stristr($values[$i], "\\n")
|| stristr($values[$i], "Bcc") || stristr($values[$i], "Content-Type") ) {
return true;
}
}
return false;
}
$error = '';
if (isset($_POST) && count($_POST)>0) {
# The form has been submitted
$course_title = $_POST['course_title'];
$course_date = $_POST['course_date'];
$course_code = $_POST['course_code'];
$course_fee = $_POST['course_fee'];
$break .= "\n";
$qual_subject_level = $_POST['qual_subject_level'];
$break .= "\n";
$email = $_POST['email'];
if ($name && $email && $subject) {
if (has_injection($name, $email, $subject)) {
# You've got another spammer at work here
$error = 'No spamming';
exit(0);
}
else {
# It's safe to send the message
mail('my#gmail.com',
$subject,
$course_title,
$course_code,
$course_fee,
$break,
$qual_subject_level,
$break,
$subject,
"From: $name <$email>");
}
}
else {
$error = 'Please fill in all the forms';
}
}
?>

One i use is have a text area and use your .css file to display:none it most bots dont read the css and thus think that the text box is shown and if it has content in it it's a bot if it does not then send your email.
E.G CSS
.antiBot{display:none};
HTML
<input type="text" class="antiBot" name="antibot" value="" />
PHP
<?php
if($_REQUEST['antibot'] == ""){
// send your email
}else{
// bot using your system
}
?>
How ever change the name or bot will get be able to notice its a trap and will get around it with little work insted of having to parse the CSS file for your site
So in your case just rap the if above around your code as for formatting of an email if its plain text use dubble quotes and \n (newline) but it wont work in single quotes.

Related

cryptic mail body when using imap_fetchbody

I am using following code to exctract among others the mail body of mails.
$imap = imap_open($mailbox,$user,$password);
$mails = imap_search($imap,'UNSEEN');
foreach($mails as $mail)
{
$message = trim(utf8_encode(quoted_printable_decode(imap_fetchbody($imap,$mail,"1"))));
if(strpos($message,"<html") !== false)
{
$mail_body = fopen($dir."mail.html","w");
}
else
{
$mail_body = fopen($dir."mail.txt","w");
}
}
This is working fine and it works with every test I did.
html-mails, plain-text-mails, also if the mails are forwarded.
Now from some other source I get mails, where the message (after using imap_fetchbody) just looks like some crypted string. Like this:
dGVpZW4gaW0gUERGLUZvcm1hdDoNClJla2xhbWF0aW9uc2luZm9ybWF0aW9uOiAyMTMzNjc0MSBS
SV8yMTMzNjc0MS5wZGYNCg0KTWl0IGZyZXVuZGxpY2hlbiBHcsO8w59lbg0KSWhyIG5vYmlsaWEg
VGVhbQ0KX19fDQoNCm5vYmlsaWEtV2Vya2UgSi4gU3RpY2tsaW5nIEdtYkggJiBDby4gS0cgfCBX
YWxkc3RyLiA1My01NyB8IDMzNDE1IFZlcmwNCg0KRGllIEdlc2VsbHNjaGFmdCBpc3QgZWluZSBL
I already tried to use some other arguments for imap_fetchbody like "1.1" or "1.2", but when I do that the message is empty.
Do you have any idea why this effect occurs?
I finally found a solution. The cause seems to be forwarded mails, that were initially sent from an apple device.
Now I use this to extract the message and it works.
$structure = imap_fetchstructure($imap, $mail);
$part = $structure->parts[1];
$message = imap_fetchbody($imap,$mail,1);
if(strpos($message,"<html") !== false)
{
$message = trim(utf8_encode(quoted_printable_decode($message)));
}
else if($part->encoding == 3)
{
$message = imap_base64($message);
}
else if($part->encoding == 2)
{
$message = imap_binary($message);
}
else if($part->encoding == 1)
{
$message = imap_8bit($message);
}
else
{
$message = trim(utf8_encode(quoted_printable_decode(imap_qprint($message))));
}

php get_magic_quotes_gpc() how can I strip the inserted escape characters?

I am in the process of building my contact forms email address validation script. Having debugged it and run basic test's using valid email addresses which all passed I went on to test for invalid addresses. My first test was .ala.dom.com which is a clear invalid with both starting and ending dots. I expected to get my error message thrown up. However; my host has set the magic_quotes on and instead the email went through because the escaped the whole local part of the address with " like this ".ala."#dom.com
This is an excert of the actual header that arrived in the email inbox -
Received: by srv28.000webhost.com (Postfix, from userid 7695918)
id 899601EE9C2; Sat, 5 Oct 2013 16:21:37 -0400 (EDT)
To: net#weedy101.netii.net
Subject: Should fold
X-PHP-Script: weedy101.netii.net/new-mail.php for 2.26.7.205
From: ".ala."#dom.com
Reply-To: ".ala."#dom.com
Content-type: text/html
Message-Id: <20131005202137.899601EE9C2#srv28.000webhost.com>
Date: Sat, 5 Oct 2013 16:21:37 -0400 (EDT)
My host's are 000webhosts.com with a free account so even though they are only using php 5.2.* I can't access the php.ini to change the setting so therefore I need to programtically strip the inserted characters, or find another work around. I am totally stumped as to how best to handle this problem. My validation script is -
<?php
if (isset($_POST['name']) && isset($_POST['message']) && isset($_POST['email']) && isset($_POST['subject'])) {
$name = $_POST['name'];
$text = $_POST['message'];
$contact = $_POST['email'];
$subject = $_POST['subject'];
$isValid = true;
$atIndex = strrpos($contact, "#");
$problem = 1;
if (is_bool($atIndex) && !$atIndex) {
$isValid = false;
$problem = 2;
}
else {
$domain = substr($contact, $atIndex+1);
$local = substr($contact, 0, $atIndex);
$localLen = strlen($local);
$domainLen = strlen($domain);
if ($localLen < 1 || $localLen > 64) {
$isValid = false;
$problem = 3;
}
else if ($domainLen < 1 || $domainLen > 255) {
$isValid = false;
$problem = 4;
}
else if (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain)) {
$isValid = false;
$problem = 5;
}
else if (preg_match('/\\.\\./', $domain)) {
$isValid = false;
$problem = 6;
}
else if (!(checkdnsrr($domain,"MX") || checkdnsrr($domain, "A"))) {
$isValid = false;
$problem = 7;
}
else if (!preg_match('/^(\\\\.|[A-Za-z0-9!#%£`_=\\/$\'*+?^{}|~.-])+$/', str_replace("\\\\","",$local))) {
if (!preg_match('/^"(\\\\"|[^"])+"$/', str_replace("\\\\","",$local))) {
$isValid = false;
$problem = 8;
}
else if ($local[0] == '.' || $local[$localLen-1] == '.')
$isValid = false;
$problem = 9;
}
else if (preg_match('/\\.\\./', $local)) {
$isValid = false;
$problem = 10;
}
}
}
else {
$problem = 11;
}
if ($isValid == true) {
$message = "Message : <br/>" .$text . "<br/><br/>" . "From: " . $name . "<br/>" . $contact;
$headers = 'From: '. $contact . "\r\n" . 'Reply-To: ' . $contact . "\r\n" . "Content-type: text/html\r\n";
$mailto = 'net#weedy101.netii.net';
mail($mailto, $subject, $message, $headers );
}
header('location: index.php?pass='.$problem);
?>
Fell free to adapt this as I am adapting it from the article "Validate an E-Mail Address with PHP, the Right Way" on http://www.linuxjournal.com/article/9585?page=0,0
<EDIT>
After running through all the help offered here and working through many experiments that is lead to I am still stuck. Although I can get things to work by copying verbatim the original reference articles example at http://www.linuxjournal.com/article/9585?page=0,0 and this is all good, what I can't do is adapt it other than changing the preg match strings which would defeat the object anyway. So if anybody can see a way to make this more adaptable, ie portable as an external function or class so it can be reused at will. I would seriously appreciate the help.
So I'm going to mark this as answered but will keep reading the comments and any new answers in the hope of one day being able to understand what exactly is stopping this subroutine from being separated out and used more flexibly.
There's a sample code directly in the documentation:
if (get_magic_quotes_gpc()) {
$process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
while (list($key, $val) = each($process)) {
foreach ($val as $k => $v) {
unset($process[$key][$k]);
if (is_array($v)) {
$process[$key][stripslashes($k)] = $v;
$process[] = &$process[$key][stripslashes($k)];
} else {
$process[$key][stripslashes($k)] = stripslashes($v);
}
}
}
unset($process);
}
You do know the filter_var function?
var_dump(filter_var('bob#example.com', FILTER_VALIDATE_EMAIL));
It's not perfect but does a way better job than you do...
PS: To validate an email first filter_var it and then use this method here (not my site but first that came up in google for php validate mx) with checkdnsrr if you want to make sure the domain can actually handle email. If no MX records are found, it's safe to assume email won't reach it. Or try a brute force port 25 socket connect too just to be really sure.
As per the new edit of my question.
Thanks all who have offered your help it is much appreciated, unfortunately I have failed to make this subroutine portable and flexible. The only way I have been able to implement it at all is verbatim as per the original article on linuxjounal.com http://www.linuxjournal.com/article/9585?page=0,0
There is a working example of this validation subroutine on my temporary home page http://weedy101.netii.net/ by all means have a play with this, and leave me a line or two of guidance too if you can.
For anybody interested I changed the placeholder text color by calling the ::-webkit-input-placeholder (plus the -moz- and -ms- equivalents) for the textarea from within a php tag inside the head element of the index page thus -
<head>
<?php
if ($problem <> 1)
{?><style type="text/css">
<!--
textarea::-webkit-input-placeholder { background: #ffffff; color: #ff0000!important; }
textarea:-moz-placeholder { background: #ffffff; color: #ff0000!important; }
textarea::-moz-placeholder { background: #ffffff; color: #ff0000!important; }
textarea:-ms-input-placeholder { background: #ffffff; color: #ff0000!important; }
-->
</style><?php } ?>

Basic Form Validation Check Number?

In this script I am checking if fields are not empty and email address is syntactically correct. How to add a text input at the bottom of my form for a basic sum question, e.g. (2+5)= I want to add a validation element to my current script to check if this equals 7.
if (empty($name) || empty($phone) || empty($email) || empty($enquiry))
{
echo " * Sorry all fields are required.";
}
elseif(!preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/", $email))
{
print "<p>Sorry the email address you entered looks like it's invalid.</p>";
}
else
{
mail($to, $sub, $mes, $headers);
print "<p>Thank you ".$name." for contacting us.<br /><br />We will be in touch shortly.</p>";
}
If you are just wanting to validate a static sum, e.g. you know it is always going to be ( 2 + 5 ) = 7
Then you could just write a simple function to check the posted value.
// this being your posted value;
$validate = 7;
function SumCheck($value){
if ( 2 + 5 == $value ){
return true;
}
else{
return false;
}
}
Then change your initial line to;
if (empty($name) || empty($phone) || empty($email) || empty($enquiry) || !SumCheck($validate))
However, I would suggest using RECAPTCHA as Robert Podwika has suggested.
1 If your session is not started use in the very first line
session_start();
2 Before form is shown. Add this code. Also remember that session start must be also in file where validation is.
$numa = rand(1,5);
$numb = rand(0,4);
$_SESSION['valid_res'] = $numa+$numb;
echo "<p>To submit form please solve this equatation $numa + $numb = ?";
echo '<input type="text name="result_val" />';
3 In validation functions you should check
if(intval($_POST['resul_val']) != $_SESSION['valid_res'])
{
echo "sorry you put wrong result in validation form";
}
However, if I were you I'd use RECAPTCHA

Form not sending, function eregi() is deprecated [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I convert ereg expressions to preg in PHP?
Escape string to use in mail()
I am trying send my form, but I get this error...
Deprecated: Function eregi() is deprecated
I tried replacing it with preg_match(), but no luck. Here is my code:
$all_valid = $name_valid = $email_valid = $comments_valid = true;
if (isset($_POST['submit'])) {
if ($_POST['name'] == '') {
$all_valid = $name_valid = false;
}
if ($_POST['comments'] == '') {
$all_valid = $comments_valid = false;
}
if (!$validator->check_email_address($_POST['email'])) {
$all_valid = $email_valid = false;
}
if ($all_valid) {
// #### NO PROBLEMS FOUND - PROCESS THE FORM DATA HERE
$mail_to = 'cat30#hotmail.com'; // recipient address
$subject = "Email from website"; // email message subject line
$name = mysql_real_escape_string(trim($_POST['name'])); // sanitize the name
if (eregi("\r",$name) || eregi("\n",$name)){ // avoid email header injection
die();
}
$mail_from = mysql_real_escape_string(trim($_POST['email'])); // sanitize their email address
if (eregi("\r",$mail_from) || eregi("\n",$mail_from)){ // avoid email header injection
die();
}
$comments = htmlspecialchars(trim($_POST['comments'])); // convert HTML characters into entities
$headers = 'From: '. $mail_from. "\r\n";
mail($mail_to, $subject, $comments, $headers);
$response = '<h2>Thanks for contacting us, will get back to you soon</h2>';
}
}
It returns a slightly different value than eregi but if I'm reading your code correctly you should be able to use the strpos() function to determine if a substring exists in a string. Eregi ignores case so you might have to combine this with a strtolower($string) call too.
Something like this:
if (strpos("\r",strtolower($name)) || strpos("\n",strtolower($name)))

Issue filtering words in contact form PHP based

I having a issue filtering bad words inside a contact form message.
It strips all the message except the first letter of the word.
Any help?
below is just getting the info
<?php
$error = '';
if(!empty($_POST['username'])) $username = $_POST['username'];
if(!empty($_POST['email'])) $email = $_POST['email'];
if(!empty($_POST['subject'])) $subject = check($_POST['subject']);
if(!empty($_POST['message'])) $msg = filter($_POST['message']);
this is the function I am trying to use to strip the bad words and replace them
$bad_words = array(
'word1' => 'gosh',
'word2' => 'darn',);
function filter($matches) {
global $bad_words;
$replace = $bad_words[$matches[0]];
return !empty($replace) ? $replace : $matches[0];
}
checks the drop down options and doesn't allow certain subjects to be emailed.
function check($str){
global $error;
if ($str == 'Mean Spirited Comment'){
$error = 'You sent a Mean-Spirited Comment';
} else if ($str =='Political Comment'){
$error = 'You sent a Political Comment';
}
return $str;
}
places the info and sends
$to = 'email#email.com';
if (!empty($subject) && !empty($msg) && !empty($email) && !empty($username)){
if ($error == ''){
mail($to, $subject, $msg, 'From:' . $email);
} else {
print $error;
}
}
?>
You could use str_replace since it can take array.
For instance:
$message = "Hello there my good friends! I am very happy to see you all today even though I feel like crap.";
$badWords = array("Crap", "Damnit", "Frack");
echo str_replace($badWords, "*", $message);
Results would be: Hello there my good friends! I am very happy to see you all today even though I feel like *.
Why re-invent new methods when PHP already offers plenty of useful ones? This should be enough to remove "bad words" from messages being sent.

Categories