Preventing E-Mail Header Injections with PHP mail()
Page last updated on 2011 / 04 / 09PHP is lauded for its simplicity in accomplishing a wide-range of tasks with the minimal amount of fuss. Sending an e-mail with PHP is extremely easy, but caution should be heeded in respect to some common pitfalls that allow your contact forms to be abused.
The following is a simple page that accepts input from a form and e-mails the required person with the form input.
<?php if(isset($_POST['from'],$_POST['comments'])) { mail('destination@example.com','My Feedback Form',stripslashes($_POST['comments']),'From: '.$_POST['from']); echo 'Thank you for your feedback!<hr />'; } ?> <form method="post"> Your E-Mail Address:<br /><input type="text" name="from" /> Your Comments:<br /><textarea name="comments"></textarea> <input type="submit" value="Send Your Feedback" /> </form>
- The form is displayed allowing a visitor to enter their e-mail address and comments
- If the form is submitted, an e-mail is sent to destination@example.com with the subject line "My Feedback Form", with the user-submitted comments in the body of the e-mail. The "From" field is added as an additional header, otherwise the e-mail receiver would only know that the form was sent from their website.
- A thank you is echoed back to the submitter
No input validation occurs (and it should), and there is no captcha-type field to prevent automated bots submitting the form.
Preventing automated bot submissions can save you or your admin team time as they won't have to sift through the kind of junk that bots are sending.
More essentially, validating form input is a must, particularly when sending mail. Because the "from" field is not validated, it is possible for the above script to be abused by adding additional headers, and even their own e-mail content! For instance, consider if the user submits the following for the "from" field:
$from = "randomaddress@nowhere.com Bcc:sendspamhere@hotmail.com,sendspamhere@aol.com,sendspamhere@yahoo.com";
Because of a lack of validation, the user has injected a new header which blind carbon copies the e-mail to a number of other (unintended) sources. Moreover, this kind of manipulation can have even more relentless variations, where your e-mail content is injected with a spam message and forwarded to hundreds and thousands of addresses, effectively turning your form into a relay for spam.
This can result in e-mail addresses from your domain getting 'blacklisted', and your legitimate e-mails will end up in spam folders or even worse, deleted before the recipient gets a chance to read them.
To prevent this unfortunate scenario, ensure that you validate any user-submitted input to prevent any potential abuses. So, a variation of the above script to prevent injections would be the following:
<?php if(isset($_POST['from'],$_POST['comments'])) { if(!preg_match("'[\r\n]'",$_POST['from'])) mail('destination@example.com','My Feedback Form',stripslashes($_POST['comments']),'From: '.$_POST['from']); echo 'Thank you for your feedback!<hr />'; } ?> <form method="post"> Your E-Mail Address:<br /><input type="text" name="from" /> Your Comments:<br /><textarea name="comments"></textarea> <input type="submit" value="Send Your Feedback" /> </form>
The slight alteration will give the sender the impression that all is working normally, but the e-mail won't actually get sent if a newline or carriage return character is present in the "from" field.
It would also make sense to apply a regular expression to validate the structure of the from e-mail address.
Tweet