What is the correct syntax to add variables such as the email address I captured on a submitted form via POST variable to my email function.

$email = $_POST['email'];

$headers = array(
'From' => 'webmaster@example.com', //I would like this to be $email variable from form
'Reply-To' => 'webmaster@example.com',
'X-Mailer' => 'PHP/' . phpversion(),
'MIME-Version' => '1.0',
'Content-Type' => 'text/html; charset=iso-8859-1'
);

    Assuming you have validated/sanitized it...

    $headers = array(
      'From' => $email,
      'Reply-To' => 'webmaster@example.com',
      'X-Mailer' => 'PHP/' . phpversion(),
      'MIME-Version' => '1.0',
      'Content-Type' => 'text/html; charset=iso-8859-1'
    );

    PS: However, looking at that, there's a good chance you host's mail server won't allow that, as it may be configured to only allow valid email accounts defined on that server to be used for the From header when using mail(). You may actually want your configured email address for From, and the user-supplied address for Reply-To -- depending on what you're actually trying to do, of course. 🙂

      Assuming you have validated/sanitized it...

      Nog dog mentions sanitizing the POST input because there's a thing called "email header injection". That's when a bad guy realizes that you are taking POST data and just using it to send out emails. Someone can abuse your code if you fail to validate the input. They'll stick in a newline character followed by a CC or BCC header line and this allows them to use your server as an open relay so they can send emails to anyone. Minimally, you should reject any $_POST['email']; value that contains a newline. Ideally, you'd use filter_var to check the user input:

      if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
          die('your email address was not valid');
      
      }

        Could one of you guys show an example of a post submission that would initiate header injection? I'm curious as to what it would look like. Is it like SQL injection where certain characters break the intended input and add a second malicious variable behind it?

        schwim

        At it's most basic, it could be CR/LF then another mail header, e.g. they might try to use it to send spam to a bunch of people via your mail account:

        "nogdog@example.com\r\nBcc: foo@example.com,bar@example.com,fubar@example.com"
        

        However, I believe recent versions of PHP have some injection sanitation built in if you use the array format for the additional headers argument, but still might be worth a little validation/sanitation. 🤷

        Assuming this code:

        $email = $_POST['email'];
        			
        $headers = array(
          'From' => 'webmaster@example.com', //I would like this to be $email variable from form
          'Reply-To' => 'webmaster@example.com',
          'X-Mailer' => 'PHP/' . phpversion(),
          'MIME-Version' => '1.0',
          'Content-Type' => 'text/html; charset=iso-8859-1'
        );
        mailto('recipient@example.com', 'regarding header injection', 'you should make extra sure to validate inputs', $headers)) {
        die('sent');

        You could construct a form to inject email headers like so:

        <form method="post" action="/path/to/php/script">
        <textarea name="email">nogdog@example.com
        Bcc: foo@example.com,bar@example.com,fubar@example.com
        </textarea>
        <button>submit</button>
        </form>

        NogDog

        sneakyimp

        Thanks very much for that. I added looking for cc: in email form elements to my autoban script.

        schwim I added looking for cc: in email form elements to my autoban script

        It sounds like you are trying to search/filter/black-list data in order to provide security. This is not the correct approach. For every value you know about in a specific context, hackers have huge lists of things that have 10 or 20 more values that you don't know about. The way to secure data isn't to try to find if it contains bad things or alter it to remove things you think are bad, it's to make sure that it is valid, i.e. of an expected format, then use it securely in whatever context it is being used in.

        For the context of a mail header, the only external user submitted value that should ever be used is an email address and then only in the Reply-to: mail header. You would validate that the trimmed, submitted value is only and exactly one properly formatted email address, which would eliminate values that contain new-line characters that would be used to inject other mail headers.

        pbismad For the context of a mail header, the only external user submitted value that should ever be used is an email address and then only in the Reply-to: mail header. You would validate that the trimmed, submitted value is only and exactly one properly formatted email address. which would eliminate values that contain new-line characters that would be used to inject other mail headers.

        Sorry for not clarifying but this had already been done in the script. The autoban system is in addition to validation of data. The autoban system is really just to save resources. If they end up on the list, it's checked at the start of the page load and if matched, I save resources by dropping them to a static HTML page. The main site I use this on is not a popular site and I still manage thousands of matches on autoban checks a month. Not having to serve those pages are the main goal of the autoban system. It's really no different than when I go to a site like Imgur and they serve me a fake "Imgur is temporarily over capacity. Please try again later." message because of my VPN service. It's just a quick check to determine whether the server should spend resources on the visitor.

          Write a Reply...