E-mail Injection Question

Posting this here since it relates to security.

I am trying to recreate this hack using PHP’s mail() function and my own different e-mails, but it isn’t working…

From:sender@domain.com%0ACc:recipient@domain.com,%0ABcc:recipient1@domain.com

Is this a case where Google and Yahoo and AT&T are stopping me, or did I screw up the syntax?

Hi @applefritters,

I’m a bit perplexed what you’re trying to do.

If your site hasn’t been having trouble getting SPAM mail complaints or been put on a blacklist, then I wouldn’t worry about your mail script too much. Just look at it to make sure it has the usual safeguards if you’re concerned.

I would not try testing it yourself. Two problems

  • you could get your site taken down by your very own host
  • bypassing email security is a lot more complex than many would think (as long as the script is up-to-date)

So it isn’t worth the effort or risk.

I am trying to prevent Form Email Injection.

That’s likes saying I wouldn’t worry about SQL Injection until it happens - not very responsible on my behalf!

Well, Form Email Injection is supposed to be a pretty big problem, and I thought it was well documented and there were good solutions for it. However, I have wasted all weekend reading up on it and trying to piece together random advice, and I am feeling frustrated that I cannot re-create it between my dev site and a few personal e-mail account I have.

If it is a fairly well-known security issue, then I would expect to be able to re-create it myself.

Maybe I did something wrong?

Sorry, that’s what I meant by

Understandting how to prevent injection is a good thing.
Trying to break it - on a live non-localhost site - is the wrong way to learn.

Does reading this help any?
https://www.owasp.org/index.php/Testing_for_IMAP/SMTP_Injection_(OTG-INPVAL-011)

Thanks for the link - it seems to be a little too general for this particular issue.

I have spent all week reading about Webform Email Injection and while I think I understand how it works, I have hit a brick wall as far as understanding if my code is properly testing for it, and it also seems I am having troubles creating the attack myself. (How can you test your code against an error when you can’t create the error?!)

This article is decent and provides some strings that should break things, but I can’t get them to work using my own e-mails…

PHP Email Injection - InfoSec Institute

Well, that’s a good thing. If you’ve tried the various ways that script-kiddies know about and they don’t work, then you know you’re safe from those vulnerabilities being used.

It is the most general things that provide the greater part of the protection.

Number one on your list should always be validation (where the field is entered by the user) or sanitization (where it isn’t user entered). This means basically either giving an error if the content of a particular field is not valid or stripping out the invalid characters.

As an example, none of the headers in an email can validly contain either a carriage return or line feed character and so as a minimum the validation of any header should give an error if either of those characters is found. Depending on the particular header there will probably be other characters that also make no sense and so should generate an error.

This helps ensure that the headers contain valid data and as a bonus also help prevent injection of additional headers.

You must have had too much Thanksgiving Day turkey or Christmas egg nog - both of which can make one drowsy - because that is what this thread is about! :stuck_out_tongue_winking_eye:

In post #5 I referenced an article discussing carriage returns and line feeds and gave an example of how a hacker could send spam via a webform…

From:sender@domain.com%0ACc:recipient@domain.co,%0ABcc:recipient1@domain.com

Where %0A is the same thing as a Line Feed

Right and so in this thread and another I am trying to get my hands around writing code to catch these things and then confirm it works through testing…

Sorry, but that is a bit naive.

What it means is maybe my test wasn’t done properly and there is still a large vulnerability.

And even if Gmail and AT&T did protect against it, it does not mean that some hacker couldn’t use my website to SPAM millions of people with a ComCast or Hotmail or whatver e-mail, right?

I wish there was someone here who knew more about this, because I really am trying to build a secure site. :frowning:

I tried the same thing as you (using my contact form as a spam relay), but like you, couldn’t get it to work.

I’m not sure how you are sending the mail and through which mail server, but in my case my hosting company was sanitizing the mail headers for me, so it was impossible for me to recreate this attack.

I consider it to be a pragmatic attitude. Security is a field of study in it’s own right and even if you were to drop all other areas of web dev it would take a lot of education to be anywhere near an expert. IMHO best to make it as difficult to abuse as possible so unless someone was extremely intent on abusing your form in particular they would move on to easier targets.

I’m sorry, I thought you said your form didn’t allow header injection. If it does then yes, you should fix it. Please post the server-side code you’re using.

I am just doing this from my laptop and MAMP - I don’t have a domain or web hosting account yet.

Not sure if I understand the mechancs, but for all of my other testing, I have been able to successfully send e-mails to my AT&T and Gmail accounts via my PHP code and MAMP.

I guess it is a good thing if Gmail or AT&T is looking out for carriage returns in the TO: line, but as I said above, that doesn’t mean the threat isn’t still there!

And I don’t want to be responsible for spamming people, so I am trying really hard to understand this hack and write code that prevents in in all cases on my site!

Agreed, but as of now, I have not written any code that addresses this issue! (And this seems like one of the first places hackers would try and attack my site.)

Again, I have no code currently which would prevent such an attack.

The problem is I also cannot create the attack on my own, so how can I write code to prevent what I cannot create?

It would be like if I needed PHP code to prevent a record from being INSERTED if there was no MemberID, but was unable to even insert a record when a MemberID was present, follow?

Everything I have read this weekend makes it sound like this is a basic script-kiddie attack, but I’m not able to create one myself.

You seem to think that means I don’t have to worry, but I see it meaning I don’t know how to hack! :smile:

Please see what I wrote in Post #8 and Post #11 because that should answer your request for code for now…

Thanks!

No, if you don’t know how to prevent email header injection, you should be concerned.

So if I finally understand

  • you have a form
  • the code is of questionable quality in terms of security
  • you tried to abuse it by sending to some of your email accounts
  • you are certain that the blocking was done at the receiving end because your code does not have any validation or sanitizition measures in place.
  • you want to be sure the form can’t be used to send emails to email clients you don’t have accounts with

You posted this topic in the Server Config category, but I’m thinking it should be moved to PHP if that’s your server-side language.
I am not so much interested in seeing what you tried, but really need to see your form code to be able to give any advice.

Hi, applefritters. For what it’s worth, I think it’s great what you’re trying to do: reproducing a vulnerability so that after you change your code, you can verify the vulnerability no longer exists. Otherwise, how could you tell whether your implementation is safe or whether you’re just not exploiting the vulnerability correctly.

Here’s a simple PHP mail form that would be vulnerable.

<?php if ($_SERVER['REQUEST_METHOD'] === 'GET'): ?>
    <h1>Contact me</h1>
    <form action="" method="post">
        <label>Your name: <textarea name="name"></textarea></label>
        <label>Your email: <textarea name="email"></textarea></label>
        <label>Your message: <textarea name="message"></textarea></label>
        <input type="submit">
    </form>
<?php elseif ($_SERVER['REQUEST_METHOD'] === 'POST'): ?>
    <?php
        $success = mail(
            'you@example.com', // to
            "{$_POST['name']} is contacting you", // subject
            $_POST['message'], // message
            "From: {$_POST['email']}" // additional headers
        );

        if ($success) {
            echo 'Mail sent!';
        } else {
            echo 'Something went wrong.';
        }
    ?>
<?php endif ?>

There are several ways you could craft your inputs to be malicious. One simple way is in the email field. You could enter a value such as:

me@example.com
To: other@example.com

It starts with the normal email value, which gets used in the From field, then a newline to start a new header. After that newline, you have full control of the email. You can set any header field as well as the body message, which means you can exploit this form to send spam to anyone you want.

The solution is to escape special characters. Every output destination has a different set of special characters. If outputting to HTML, you escape angle brackets and quotes, because those are the characters special to HTML. If outputting to SQL, you escape quotes and backslashes. If shell command or JSON, then you escape the special characters of those respective destinations. And so on.

For MIME headers, the newline itself is a special character, among others.

Your options are 1) read rfc2822 very carefully so you can escape correctly, or 2) use a library. I strongly suggest the latter. :wink: There are several to choose from, but my top choice is SwiftMailer.

Here’s the same script from above but rewritten using Swift.

<?php if ($_SERVER['REQUEST_METHOD'] === 'GET'): ?>
    <h1>Contact me</h1>
    <form action="" method="post">
        <label>Your name: <textarea name="name"></textarea></label>
        <label>Your email: <textarea name="email"></textarea></label>
        <label>Your message: <textarea name="message"></textarea></label>
        <input type="submit">
    </form>
<?php elseif ($_SERVER['REQUEST_METHOD'] === 'POST'): ?>
    <?php
        require_once __DIR__.'/swiftmailer/lib/swift_required.php';

        $message = Swift_Message::newInstance()
          ->setSubject("{$_POST['name']} is contacting you")
          ->setFrom($_POST['email'])
          ->setTo('you@example.com')
          ->setBody($_POST['message'])
          ;

        $transport = Swift_SendmailTransport::newInstance(ini_get('sendmail_path'));

        $mailer = Swift_Mailer::newInstance($transport);

        $nSuccessfulRecipients = $mailer->send($message);

        if ($nSuccessfulRecipients) {
            echo 'Mail sent!';
        } else {
            echo 'Something went wrong.';
        }
    ?>
<?php endif ?>

Even though we’re still using user inputs directly, Swift keeps you safe from injection.

1 Like

That’s me!

As I stated in Post #8, I tried to trick PHP mail() into thinking that I wanted to CC the Comment to other e-mail addresses.

From what I understand, this entire exploit happens when the hacker adds a CR/LF to the end of either the $to, $subject, or $message parameters. This allows them to then append a list of e-mails that could be sent as CC’s or BCC’s even though my physical form only asks for the user’s email, name and comment/question.

From InfoSec Institute

Or maybe I messed up the hacking string which broke my attempt to spam my personal e-mails.

More correctly, when a registered user or a random visitor submits a comment/question, I want to make sure they don’t add code to the FROM:, SUBJECT: or MESSAGE: which allows them to trick my PHP script and send spam - using my website - to one or more unsuspecting victims under the guise of coming from my website.

I posted here because there is no “Security” forum and the note said to post here. But, yes, the PHP forum might also be a place to stick this thread.

As far as code, I don’t mind sharing, but there isn’t much to share at this point.

My form has 3 fields:

  • Your Email (req)
  • Your Name (optional)
  • Your Comment/Question (req)

When the form is submitted, code under this block will validate and sanitize things…

    if ($_SERVER['REQUEST_METHOD']=='POST'){

I plan on using PHP’s

 filter_var($email, FILTER_VALIDATE_EMAIL)

I will also use my own Regex.

And frankly, those two things may be enough on their own, HOWEVER, I am trying to learn something new here.

So I would like to learn how to be 100% certain that there aren’t any control characters or whatever that could break my code, if you follow me?

And working with things like 0x0D are Greek to me!

I have another thread under the PHP section trying to understand these special characters, but this thread is about better understanding how the actual hack and code works.

Hope that makes sense!!

Hi Jeff, and thanks!

What you have said so far is consistent with what I have been reading.

From everything I have read, all I need to look for is Newline and Carriage Return, right?

I don’t mean to ignore your suggestion, but my fear is that this is some application I would have to install and configure on my VPS and that is more than I want to do.

Maybe down the road I could look into it, but I am still pretty new to web development, let alone being a system administrator.

The purpose of this thread was to figure out why when I try the hack I was reading about, it doesn’t work. (I think getting beyond that barrier is important, but I’m not sure what to do.)

As far as escaping things, I do have some questions about that topic here…

Questions about Control Characters

Great example, Jeff!
I tried this out and was able to spam myself (yay), leading me to conclude I must have done something wrong when testing previously.

Swift is a PHP library that you should just be able to drop into your project with a minimum of fuss.
I would at least give this a go.

I would be interested to know how you accomplished that, because I spent all day Sunday trying to recreate the email header injection hack using a couple of my Gmail and AT&T accounts and it appears that both Google and AT&T are smart enough to disallow such an e-mail.

I’ve got no better knowledge to add here than these very helpful and patient people, but I do have one thing to say about the general tone you’ve taken in the thread.

So say I have a house, and I’m working on improvements. And I see a suspicious looking character on a nearby street, and I get to thinking. So I put in an alarm system. But you know, that’s only protecting against a certain caliber and type of intrusion… so I decide I’d better bar the windows too, and get a second deadbolt for every door. But then I hear about a shooting on the news, so I go and put up a privacy wall around my property, with floodlights and cameras.

Eventually I’m broke, have wasted all of my time and money, and my house is far, far over secured in a ratio to its actual value.

Security is good, and learning is good. But don’t lose sight of the scope of it.

And try not to be rude and dismissing of people who are helping you for free :wink: