I have a classifieds website, and inside each classified, there is a small form.
This form is for users to be able to tip their "friends":
<form action="/bincgi/tip.php" method="post" name="tipForm" id="tipForm">
Tip: <input name="email2" id="email2" type="text" size="30 />
<input type="submit" value="Skicka Tips"/>
<input type="hidden" value="<?php echo $ad_id;?>" name="ad_id2" id="ad_id2" />
<input type="hidden" value="<?php echo $headline;?>" name="headline2" id="headline2" />
</form>
The form is then submitted to a tip.php page, and here is my Q, is this below code safe, ie is it good enough or do I need to make some sanitations and more safety details?
$to = filter_var($_POST['email2'], FILTER_SANITIZE_EMAIL);
$ad_id = $_POST['ad_id2'];
$headline = $_POST['headline2'];
$subject = 'You got a tip';
$message ='Hi. You got a tip: '.$headline.'.\n';
$headers = 'From: Tips#domain.com\r\n';
mail($to, $subject, $message, $headers);
I haven't tested the above yet.
You are passing $ad_id and $headline to the HTML only to have it passed right back, unchanged. Since ad_id and headline are not editable in the form, don't put them on the form, keep them on the server. That's the most secure.
Regardless of what filtering you do, you'll need to rate limit the sending of these emails. Even if they look to be from you and have some site-specific text, an automated bot could spam several hundred thousand of them and get some kind of response (and blacklist your email server). Only let them send a handful every hour and you won't cut out legitimate traffic.
It's a good idea to sanitise the input before you use it. Check to ensure the two post variables are in the correct format (e.g. only text or numeric (using Regex or is_numeric etc))
It looks like you have XSS in $ad_id = $_POST['ad_id2']; and $headline = $_POST['headline2'];.
There is a security concern with mail(). You must be careful of CRLF injection \r\n in $headers. in this case $headers is not controlled by the attacker, so you have nothing to worry about. Another point although its called CRLF injection, it could also be called LF injection because a new line is all you really need because SMTP is a forgiving protocol.
If $headline comes from your own database, I would not put the text in a hidden field, but the id of the headline and retrieve the actual text from the database before sending the mail.
That way you can A. simply check if the id is really an integer and B. know for sure only valid headlines get sent; now someone can post your form replacing your headline with any text they want.
Related
I want that in PHPMailer, the SetFrom is a filled in field.
$mail->setFrom('filled-in#field.com', 'Smaragd Express');
Does anyone know how I accomplish that?
Regards,
Joren
To get a form field into your script is very simple. In your HTML:
<input type="text" name="from">
When that's submitted it will turn up in your PHP script in the $_POST super global, and you can pass it to the setFrom method:
$mail->setFrom($_POST['name'], 'Smaragd Express');
However, you should not do this. Setting the From address to arbitrary values like this is forgery which will cause CPF checks to fail and your messages will either be rejected entirely or end up in spam folders. Instead, put your own address in the from address and the submitted address in a reply-to:
$mail->setFrom('me#example.com', 'Smaragd Express');
$mail->addReplyTo($_POST['name'], 'Smaragd Express');
I'll be thrilled with any solution that will do that. Here's what I've been trying:
I have an input form that gets variable info. I want to email using php mail(), the variable info that was input. I've put the php mail() later in the same html/php file (I haven't used js in here at all). I can't figure out how to access those input variable values, to put into the mail() function.
<form target="_blank" action="https://www.paypal.com/cgi-bin/webscr" method="post"> <br>
Donation Amount $: <input type="text" name="amount" size="20"> <br>
Instructions to us:
<textarea name="eventcardinstructions" rows=6 cols=60></textarea><br>
<input type="hidden" name="add" value="1">
<input type="hidden" name="cmd" value="_cart">
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_cart_SM.gif" border="0" name="submit">
etc.
</form> <!-- closes the form and lets the user hit a submit button-->
This is collecting inputs from the user to send to paypal. It's working. The user inputs an amount into an input field and instructions into a textarea. The amount is sent to paypal. The textarea instructions ARE NOT SENT to paypal, which is what I want.
Later (before the form ends OR) after end of form and the submit button that sends this to paypal, I want to reference the "amount" and "instructions" in php mail() function. The mail() function is working and sends emails. It just ignores and doesn't send the variable amounts. So the emails say:
Subjectline: Event Card
Body contents: Event card bought for
The mail function is:
<?php
// headers allow the email to recognize html with in the
// message & process it.
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
$eventcardmsg = "Event card bought for " . $_POST['amount'];
$eventcardmsg = $eventcardmsg .= $_POST['eventcardinstructions'];
mail("email#ourdomain.net", "Event Card", $eventcardmsg, $headers);
?>
How do I setup amount and eventcardinstructions so the values are used?
I see a couple related q&as but can't figure it out from them. This answer is using it the same way I am by using the $_POST['variable']; but it's not working for me.
https://stackoverflow.com/questions/30016669/how-do-you-save-a-inputs-value-in-a-variable
This one:
Assign input form to a variable looks like it's using php in the middle of the html input form to set the variable. I could try that, but seems odd to need to, like I'm not understanding something.
Thanks!!
First, as TomasH already pointed, your $eventcardmsg assignation is wrong.
Anyway it might be simplified like this:
$eventcardmsg =
'Event card bought for ' . $_POST['amount'] . ' ' . $_POST['eventcardinstructions'];
(don't omit at least one space between amount and instructions)
Now if you keep getting an wrong email content, the main question in this issue is: are POST query parameters sent to your PHP script?
So you should test it with something simple like:
<?php
echo '<pre>' . print_r($_POST, true) . '</pre>';
Then if it shows empty parameters (or even those parameters not cited), you must examine the way you're sending data from the HTML page.
Again already pointed by TomasH, it might be somme inconsistency while you previously send data to Paypal: if you don't identify it, please edit your question to show us the whole Paypal process.
EDIT (trying to answer the multiple OP's comments)
Regarding string concatenation in general
You may concatenate as many strings as you want into a resulting string, using the . operator, so:
$a = 'A';
$b = 'BB';
$c = 'CCC';
echo $a . $b . $c; // prints ABBCCC
Regarding .=
Any operator (not only .) may be used in conjunction with =, as a shortcut to avoid repeating the 1st operand when it is also the result, so:
$result .= $ope2;
// the above expression is pretty equivalent to the one below
$result = $result . $op2;
Regarding comments related to your original issue
It's not clear what you exactly want now, because you said:
I don't really want to send the form to a php file of my own.
But your original question tells you can't emit a proper email, and to emit an email you must first send the form to the php file where you emit it!
Anyway, you should test like I previously suggested:
echo '<pre>' . print_r($_POST, true) . '</pre>';
This way, you will get the whole list of which POST query parameters are passed to your script: print_r() is the function that prints this list, and <pre> is the enclosing HTML tag that makes this print more readable.
Be careful to type the statement exactly: from your penultimate comment, I guess you typed something wrong.
I have a form and this bit of code to send it:
if($feedback != $errorMessage){
$emailTo = 'me#mywebsite.com';
$emailFrom = 'submissions#mywebsite.com';
$subject = 'Submission';
$body = filter_var("$contactName made a submission.
Contact Information:
Contact Name:\t$contactName
blah:\t$blah
Address:\t$address
Telephone:\t$telephone
Mobile:\t$mobile
E-mail Address:\t$userEmail
Website:\t$website
Vacancy Information:
field1:\t$field1
field2 Benefits:\t$field2
field3:\t$field3
field4:\t$field4
field5:\t$field5
field6:\t$field6
field7:\t$field7
field8:\t$field8
field9:\t$field9", FILTER_SANITIZE_STRING);
mail($emailTo, $subject, $body, "From: ".$emailFrom);
}
From what I understand from reading other threads this should be enough. I tried emailing just a single dot on a line in one of the textareas and it did turn it into 2 dots. Just running one function on it seems far too simple though.
Is this secure enough? I've read things online that seem inconsistent like that I don't even have to sanitize the body. The email body is the only thing that takes user input here.
Thanks.
Not entirely sure what you mean by secure here. Your script is just sending an email. The content of the fields will be what the user filled in. It could be link to virus, crap, spam or real content. Not easy to say, really. Not much to do with it either.
Sanitizing is much more important once databases are in use.
I am a PHP newb so please bear with me for this rather simplistic question.
I have a PHP form setup like so >>
<?php
if($_POST){
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$comments = $_POST['comments'];
if($comments)
$error = "There was an error, please give us a call at ### ###-####.";
else{
if($name=="Name" || $email=="Email" || $message=="Message"){
$error = "All fields are required, please fill them out and try again.";
}else
$header = "From: $name <$email>";
$message = "Name: $name\n\nEmail: $email\n\nMessage: $message";
if(mail("email#domain.com", 'Form Submission', $message, $header))
$success = "Thanks for sending us your message, we'll get back to you shortly.";
else
$error = "There was an error, please give us a call at ### ###-####.";
}
if($error)
echo '<div class="msg error">'.$error.'</div>';
elseif($success)
echo '<div class="msg success">'.$success.'</div>';
}
?>
The basic idea is that the form has descriptive text pre-filled in each field but when you click on them they are cleared via Javascript. I want to prevent people from pressing send on the form without filling it out, hence the "if($name=="Name" || $email=="Email" || $message=="Message"){" bit. However while that message is working the form is still submitting. Why is this. Also please note that the "comments" field is in fact a honeypot. Thanks!
Because php is server-side. You need to look into javascript validation for what you want. To validate with php you HAVE to submit the form.
One tutorial but I recommend Jquery validation
"I want to prevent people from pressing send on the form without filling it out, hence the "if($name=="Name" || $email=="Email" || $message=="Message"){"
All you need to do is disable the submit button client side until the proper validation is met, then also validate server side. As #Iznogood said, that's why your gettin your error
Like lznogood said, PHP validates the form on the server, so you need to send the information to the server before PHP can process it.
If you want the form to be checked on the user side before sending it to the server you should use JavaScript to do that (jQuery is a great tool to use), and after checking it on the user side you can decide whether to send the form to the server or not.
Though this isn't an answer to your question, you might be interest in the new html5 feature placeholder. Read about it here. You can check to see which browsers it works in here (stupid internet explorer!). 5 years ago, I would put those "hints" as the value, which was a pain to validate. placeholder makes it sooooooo much easier. Your tag would look like:
<input type="text" name="email" placeholder="Enter Your Email Here" value="">
Note that value is empty. You can omit the value attribute, I left it in to show it's not needed here.
As far as an answer to your original question, everybody else is correct, javascript is the way to go.
So, basically, I'm creating a page where a user can visit, and enter in the following information:
1. Their First Name
2. Their Email
3. Recipient's Email
They then can send a pre-defined email, saying something like the following...
"Hello, {Recipient's email}. {First name} ({Email}) has just sent you a slurp! You can ignore this message, or slurp them back.
[Slurp Them Back] [Slurp Someone Else] [What's A Slurp?]"
The whole part about the Slurp is something that doesn't really matter, it's just the text from the pre-defined email. The text in {...} is taken from the fields on the page, and the text in [...] are just links.
Does anyone have any idea on how to do this? Even if you can't customize the email, and it would just be without the information from the site, help would be appreciated. Thanks.!
Here's an example of what I'm going for...
Example Layout
It's possible to do using the php mail function. You can take input for everything you specified, then use the example here. They show it in a basic and more advanced form.
Interestingly, the first chapter of Head First PHP describes almost exactly this scenario (except that the recipient is fixed). If you want to learn more about PHP you can look into the book; otherwise, their code is online at http://www.headfirstlabs.com/books/hfphp/ (actual code link: http://www.headfirstlabs.com/books/hfphp/code/HeadFirstPHPMySQL_code_ch01.zip)
Sending an email by itself can be done by using the mail() command
mail('to.address#host.com', 'subject', 'message', 'From: from.address#host.com');
The whole code would look something like this:
HTML:
<form action="slurping.php" method="post">
Your name: <input type="text" name="name" /><br />
Your email: <input type="text" name="email" /><br />
Recipient: <input type="text" name="recipient" /><br />
<input type="submit" />
</form>
PHP (slurp.php):
// order of parameters is: to, subject, message body, additional headers
mail(
$_POST['recipient'],
'You just got slurped',
'You\'ve been slurped by '.$_POST['name'].'. Slurp him/her back by visiting http://slurp.com/',
"From: {$_POST['email']}\r\n"
);
This will send out an email like it's coming from the senders email address to the recipient.
There's a lot missing there, though. What you normally want to include is:
Validation of input on the client side (javascript)
Validation of input on the serverside
Clear out and handle right encodings etc
If you want to do it properly however, so that a greater percentage of your users actually receive the email, you should use a 3rd party library to send out emails. I recommend PHP Mailer or Swift Mailer.
Those libraries provide an easy mechanism for you to include HTML in your emails, attachments, allow for easily connecting to SMTP servers and handle all escaping and encoding issues for you.
On top of that they encapsulate everything within an Object oriented approach, so if that's your cup of tea, you'll be happy. Se their websites for more info.
It's pretty funny, I wrote a blog post about the very issue of email deliverability (getting through spam filters) etc: http://arnorhs.com/2011/02/21/delivering-email-with-php/ - It might be helpful to you.
Cheers
On submit you can send a predefine email in php
following is the code sample
assumed that you will have a html page and following is the sample html code
Send Slurp
Enter Your Name:
Enter Your Email:
Enter Recipient's Email:
following is the php code in "="send_email.php"
if ($_SERVER["REQUEST_METHOD"] == "POST")
{
$your_name = $_POST['your_name'];
$your_email = $_POST['your_email'];
$recipients_email= $_POST['recipient_email'];
$email_subject = 'My Slurp';
$email_body = "Hello, $recipients_email. $your_name ($your_email) has just sent you a slurp! You can ignore this message, or slurp them back.
[Slurp Them Back] [Slurp Someone Else] [What's A Slurp?]";
echo $email_body;
// Send Email
mail($recipients_email, $email_subject, $email_body);
}
?>