Barely a week goes by without someone asking for help with a PHP
mail() script that uses one of the most insecure techniques—inserting unfiltered user input into the headers argument. It exposes your server to email header injection, an exploit that can turn your website into a spam relay. This exploit has been known for many years, and I warn about it in all the books I’ve written on PHP. But beginners still blithely ignore the dangers.
The problem is that the fourth argument to the
mail() function lets you specify custom headers. So, it’s become almost routine to create a From header with the user-submitted email address. There are two things wrong with this:
- The From header is meant to indicate where the email originated from. When you use the
mail()function, it’s your website that originates the message, not the person submitting the form. If you want to use the submitted address, it should go in a Reply-to header.
- You should never trust user-submitted input without checking its validity. Email header injection relies on unfiltered data being passed as the fourth argument to
What happens is that the attacker uses the email input field to inject Cc and Bcc headers plus a replacement message body. Avoiding this problem is simple. All that’s necessary is to check the validity of any values that are added to the headers. I’ve created a simple tutorial explaining how to do it—and keep safe.