PHPMailer - Does body have to come from a file now? - phpmailer

I've been using PHPMailer successfully for a couple of years. I just refreshed my PHPMailer class from their github site, and now my server throws 500 errors. I tracked down the problem to this line (simplified for this post):
$mail->Body = "<p>Hello World</p>";
All of the example that I see on the worxware website these days show the body of the email being read from a file like this:
$body = file_get_contents('contents.html');
$body = eregi_replace("[\]",'',$body);
$mail->MsgHTML($body);
I also tried modifying my code to use the MsgHTML syntax, but I still have the same result:
$body = "<p>Hello World</p>";
$mail->MsgHTML($body);
I can't imagine that it matters whether this body gets populated from a file or from a local variable, but nothing that I try works. What am I missing? Thanks!

$output = str_replace(array("\n","\r"),"",$output);
try this

Related

Linux mail: when i try to send attachment body is also attachment

i try to send a mail from a bash script with the following code
notify_by_mail () {
echo "TEST BODY" | mail --attach=$LOG_PATH -aFROM:$1 -s "Borg backup failed" $2
}
The problem is, what I try to echo to mail is also handled as an attachment but I want to have it as the body. When I dont send an attachment it behaves like I would. Could anyone please tell me whats going wrong?
It tried around with mail and searched long for the options but I cant figure out what I do wrong.
Thanks a lot!

Am I safe (XSS injection, etc) with my website contact form with Google Captcha?

I have suffered injection in my website (from a search box in a KB system). I removed that KB system but have a Contact Form (with Google Captcha) where the user enters his name, email and message and I use PHP mail() to send me the message.
Is it possible that an attacker can get access to my website from a possible attack to that form? Or the worst scenario could just be that he uses it to send Spam?
This is my PHP code before calling "main()":
<?php
$fname = $_POST['contact-f-name'];
$lname = $_POST['contact-l-name'];
$email = $_POST['contact-email'];
$text = $_POST['contact-message'];
$companyname = $_POST['company-name'];
$subject = $_POST['subject'];
$address = "myemail#myemail.com";
$headers = "From: " . strip_tags($email) . "\r\n";
$headers .= "Reply-To: ". strip_tags($email) . "\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-type:text/plain; Charset=UTF-8 \r\n";
$message = ."Name: ".strip_tags($fname)." ".strip_tags($lname)."\r\n"
."Email: ".strip_tags($email)."\r\n"
."Company Name: ".strip_tags($companyname)."\r\n"
."Subject: ".strip_tags($subject)."\r\n"
."Message: ".strip_tags($text)."\r\n";
if(#mail($address, $subject, $message, $headers)) { echo "true"; }
else { echo "false"; }
exit;
?>
TL;DR: Short answer: Maybe:
While I do not have the time right now to do a complete and exacting answer to this post; I will point you to some best practises, and lots of links to other more verbose answers to similar questions regarding making user inputted data safe.
How to make the inputs safer?
Disable certain dangerous PHP functions. Read the second answeer rathr than the "ticked" answer.
Use PHPs filter_var() to force input the their correct types, especially for emails:
$email = filter_var($_POST['contact-email'], FILTER_SANITIZE_EMAIL);
use preg_replace() (or str_replace() ) to remove unwanted characters from your values. This can most typically be backticks, quotes of any kind, forward slashes or backslashes. Example.
I recommend replacing mail() in your code with PHPMailer.
strip_tags is ok, but just ok. It has flaws (such as dealing with unclosed tags). be aware of that.
Your PHP should be suitably jailed so if someone can run exec(...) commands (Ohsh1tOhsh1tOhsh1t) you have not (literally) lost your server.
What else can I read?
This huge topic on how to deal with forms on PHP
This question about how to "sanitise" user input.
OWASP PHP filters for cleaning inputs.
Disable dangerous functions
PHP fitler_var sanitisation filter list
Securing user variables (database related mostly)
Further wise words on data sanitisation.

Example using poor-smime-sign

I am trying to send SMIME signed email and fail.
I use Python 3, so I chose the poor-smime-sign library.
Using Thunderbird to recieve, I either get an empty email with "undisclosed recipients" and no subject, which is signed or I get the whole thing in plain-text, printing a huge blob of base64 with the message-body - no sign of signing (pun unintended, noticed and left intact).
I have compared the source of a working email (created by Thunderbird from my sent folder) with my franken-mails, but I don't quite see the difference.
Here's the code:
from poor_smime_sign import smime_sign
def signEmail(self, message :str) -> str:
"""Sign the message-body.
The message is encoded in UTF-8, signed and then returned as Unicode.
Check this document on how to generate untrusted example-keys:
https://tools.ietf.org/doc/python-m2crypto/howto.smime.html
Check the settings ('invmail'->'keydir') where to put the keys.
The privateKey is called 'signer_key.pem' and publicKey 'signer.pem'.
"""
import os
privateKey = os.path.join(settings.SF.mail['keydir'], 'signer_key.pem')
publicKey = os.path.join(settings.SF.mail['keydir'], 'signer.pem')
try:
signed = smime_sign(publicKey, privateKey, message.encode('UTF-8'))
except Exception as e:
raise(Exception("Problem during signing: "+str(e)))
return signed.decode('UTF-8')
poor_smime_sign btw is pretty humble about their module, which I quite like. I looked at their code and all they do is call openssl, which is what I would have done, too, as the next step. If you're troubleshooting you can go into the mod and log the command that gets executed and fiddle with that in a shell until you understand why it fails. I e.g. had pub and priv cert the wrong way and got a really stupid error message.
This is what puts the message together in the end. I had copied it from some example somewhere.
body = self.signEmail(body)
emailAr = [
"From: %s" % emailFrom,
"To: %s" % emailTo,
"Subject: %s" % subject,
"", # <- that one
body,
]
message = "\r\n".join(emailAr)
#...
server.sendmail(emailFrom, [emailTo], message.encode('UTF-8'))
TL;DR:
Get the headers right: Signing already creates a header. Just add to that. No empty new lines.
Well, turns out I had no idea how email works. I was indeed wondering about why I use the TO-address twice (once constructing the message and once in sendmail()) but it took a while until I figured it out. I knew, that I needed some sort of header but I did not know where and why.
The solution was twofold:
The text that gets signed needs a header so the email client knows what to do with it. I took one from a working email I had lying around.
Looks like this.
cannedHeader = "\r\n".join([
"Content-Type: text/plain; charset=utf-8; format=flowed",
"Content-Language: de-DE",
"Content-Transfer-Encoding: quoted-printable",
"","" # emtpy new line concludes header
])
body = cannedHeader+bodyInput
body = self.signEmail(body)
The signed message-body already comes with a partial header attached to it. Printing out the result of signing, you see it starts with
MIME-Version: 1.0 Content-Type: multipart/signed;
protocol=3Dpplication/x-pkcs7-signature"; m= icalg=3Dha-256";
boundary=3D---DF20A931579CC3CE98F68AEF4D387131"
This is an S/MIME signed message
------DF20A931579CC3CE98F68AEF4D387131
And I ran that through the initial version of the code, generating two headers in the process. One with recipients and subject suffixed by an empty new line, and then added the signed message-body, which had another header, containing SMIME information, also suffixed by an empty new line. That could not work. So removing the empty line (in the question marked with "that line") fixed this.
As I have not found any example on stackexchange, I thought I'd write this down, so I can find it when I need it the next time.

Sign MimeBodyPart which has attachments in it (with Bouncycastle)

I am working with OpenAS2Server-1.3.3 library.
There sending a single document is working fine..
Now I wanted to modify it to send document with attachments, like we do with emails. In this scenario, all the decription work well, but signature verification failed (MIC is not matched)
This is how I am tring to send attachments with main doc:
Create a MimeMultipart and add two MimeBodyPart into it. (main document and the attachment)
Finally wrap the MimeMultipart within a MimeBodyPart (I am not sure this is the way to do this, but anyway Bouncycastle do not have API to sign MimeMultipart )
Could anyone tell me the correct way to sign a message with attachment ?
MimeBodyPart mainBody = new MimeBodyPart();
mainBody.setDataHandler(new DataHandler(byteSource));
MimeBodyPart attachemt1 = new MimeBodyPart();
attachemt1.attachFile("/home/user/Desktop/Test1.txt");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(mainBody);
multipart.addBodyPart(attachemt1);
MimeBodyPart body = new MimeBodyPart();
body.setContent(multipart);
body.setHeader("Content-Type", multipart.getContentType());
logger.info("--------------Attaching the file... Done");
I was able to get the issue and solution. I am just putting it here for anyone else who will try to do this kind of work.
I just dump the data that use for calculating MIC, at both sending side and receiving side. So the attached image will show the problem clearly.
So I added those header fields manually for all the attachments and main doc, at the sending side, as bellow.
mainBody.setHeader("Content-Type", "application/EDI-X12");
mainBody.setHeader("Content-Transfer-Encoding", "7bit");
Now it solved and "MIC is matched".

gmail url variables

I've set up my mailto links so that they open Gmail.
// you can code a url like this to push things into gmail
https://mail.google.com/mail/?view=cm&fs=1&tf=1&to=user#example.com
I understand there are several other variables:
&su= // email subject
&body= // body text
&disablechatbrowsercheck=1 // pretty self explanatory
The thing is I can't find a list anywhere with the possible ones.
Has anyone composed such a thing or found such a list.
Edit: You can now resort to classic mailto links to pass subject and body params:
email here
why bother doing that ? the mailto link will open the default mail client you have installed
i think having gmail notifier installed is enough
and that will be better to users with no gmail.
see here Making Gmail your default mail application or this Make mailto: links open in gmail
if not i found this example from here:
https://mail.google.com/mail?view=cm&tf=0" +
(emailTo ? ("&to=" + emailTo) : "") +
(emailCC ? ("&cc=" + emailCC) : "") +
(emailSubject ? ("&su=" + emailSubject) : "") +
(emailBody ? ("&body=" + emailBody) : "");
The example URLs for standard gmail, above, return a google error.
The February 2014 post to thread 2583928 recommends replacing view=cm&fs=1&tf=1 with &v=b&cs=wh.

Resources