Live data from Hacker News

PHPMailer Exploit – Remote Code Execution

legalhackers.com

31–40 of 109 posts

Re: PHPMailer Exploit – Remote Code Execution

#31
post #26
post #23

Earlier quoted context omitted.

This is incorrect. Input sanitisation is not the problem here - PHPMailer sanitises and validates email addresses well enough. The problem is that a valid, sanitised email address can also be an attack in an inappropriate shell context . Much as an SQL injection attack string may be harmless in a shell context but lethal in SQL. Also the vuln does not apply to CLI sendmail, only when sending via the PHP mail() functi…

I am not blaming lack of input sanitization, the bug is clearly still there. What I am saying is that input sanitization would prevent this attack because it will only allow valid characters to get to your mailer, which will exclude spaces, tabs, double and single quotes. Thus I fail to see an exploit vector which would bypass proper input sanitization. Do you see it? In general I agree that PHP mail() function shoul…

> What I am saying is that input sanitization would prevent this attack because it will only allow valid characters to get to your mailer,

you have to be careful with the meaning of "valid" though: What's valid in one context might not be in another context. Do you want to limit the character set to the least common denominator of non-special characters valid in all possible contexts your address might be used?

What if you don't exclude some character because it's not special in any of the current contexts but then you later add another thing to the mix that uses in-band signalling? Now you need to update your whitelist and remove even more "invalid" characters.

This won't end well for you.

I would recommend you don't put a restriction on the input (aside of what the RFC defines as valid) and instead correctly escape (or throw if your context doesn't support escaping) when moving the raw data to a new context.

In this case, I think the problem is in PHP's `mail()` function that put stuff in shell context without any escaping.

The fix should be happing in `mail()` (which is internally shelling out and thus switching context), not in the caller and certainly not in the frontend controller when it needs to decide whether a given email address is valid or not.

Re: PHPMailer Exploit – Remote Code Execution

#32
post #28

Earlier quoted context omitted.

Misguided developers incorrectly "validating" email addresses is the reason that one of my clients couldn't use one of the newer TLDs, ".place", and ended up scrapping it and trying to find something they wanted a lot less in the much more crowded .com space. It's also why I far-too-often run into forms that won't let me use a "+" in the username part of my email address, which I use to track who's responsible for se…

Genuinly curious: does '+' trick work? I would imagine any infringing parties would learn to remove plus sign and all after it before selling the database of addresses by now... Other than that: true, I hate incorrect validation. But I hate sloppy security practices even more.

Not as much as it used to. You're right, they've caught on to it. I need to stand up another mail server pretty soon, I want to try making it easy to generate random recipient aliases, so e.g. qti3XZ@mydomain.com is an alias for rob+someservice@mydomain.com and gdUTgp@mydomain.com is an alias for rob+otherservice@mydomain.com. That oughtta stump 'em for a while.

Re: PHPMailer Exploit – Remote Code Execution

#33
post #24

Earlier quoted context omitted.

Or, y'know, treat user input as untrusted. Radical, I know. And all the wooooork this would be to implement! Calling filter_var($sender, FILTER_EMAIL). Nah. Better throw it out completely and use mail() directly, that would be way safer. #sarcasm

That doesn't help - user input is already validated by default in PHPMailer - the problem is that a valid email address can also be an attack string in a shell context, and bugs in PHP make it hard to work around safely.

Really? So you're saying this is a valid e-mail address?

    "\"Attacker\\' -Param2 -Param3\"@test.com"
Let's try it:

    

Re: PHPMailer Exploit – Remote Code Execution

#34
post #31
post #26

Earlier quoted context omitted.

I am not blaming lack of input sanitization, the bug is clearly still there. What I am saying is that input sanitization would prevent this attack because it will only allow valid characters to get to your mailer, which will exclude spaces, tabs, double and single quotes. Thus I fail to see an exploit vector which would bypass proper input sanitization. Do you see it? In general I agree that PHP mail() function shoul…

> What I am saying is that input sanitization would prevent this attack because it will only allow valid characters to get to your mailer, you have to be careful with the meaning of "valid" though: What's valid in one context might not be in another context. Do you want to limit the character set to the least common denominator of non-special characters valid in all possible contexts your address might be used? What…

I think you are taking my argument too far. Valid input doesn't mean it is safe to use in any context. It just means that anything which is invalid at the start shouldn't even have the chance to get in the system.

You should still properly escape data when passed to another context, no doubt about it.

I am also not suggesting "dirty" practices like replacing double quotes (Wordpress) or magically escaping quotes on input (PHP prior to... 5?). But if you know the input should be a number, allow only digits and '.' and clean everything else. And validate the range too! If you need a database ID, validate form and existence. If you need an e-mail address, run it through filter_var. Always. There is no reason not to.

Re: PHPMailer Exploit – Remote Code Execution

#35
post #30

This discussion is broken by design. Using user input from contact form as "From" address for emails, sent from your site, is the mistake of your application - you should use something like "noreply@yoursite.com", why you put user email there? In addition - most probably such emails will not pass spam filters.

It depends on whether you want to follow RFCs or not. Particularly, RFC 4021 [1] states that:

  Header Field: From

      Specifies the author(s) of the message; that is, the mailbox(es)
      of the person(s) or system(s) responsible for the writing of the
      message.  Defined as standard by RFC 822.

  Header Field: Sender

      Specifies the mailbox of the agent responsible for the actual
      transmission of the message.  Defined as standard by RFC 822.
As far as I understand, this means that yes, you should set the From address to the user's email when sending content submitted by that user. In contrast, you should never set the Sender address to any user's email.

Another discussion is whether this is sensible or not, how well it works delivery-wise, etc... In any case, it is not as clear-cut as you make it seem.

[1] https://tools.ietf.org/html/rfc4021#section-2.1.2

Re: PHPMailer Exploit – Remote Code Execution

#36

Out of curiosity, why is PHPMailer invoking the command line at all? It would seem much safer to establish a TCP connection to the local MTA over port 25 or 587 and send the message that way. Admins can just use iptables to restrict access to the port to localhost, and/or do the same in their MTA config.

Using command line is the standard way in Linux and de-facto standard in *nix world. "To deliver electronic mail (email), applications shall support the interface provided by sendmail (described here). This interface shall be the default delivery method for applications." http://refspecs.linux-foundation.org/LSB_3.0.0/LSB-PDA/LSB-P...

Yes but PHP runs on non-*NIX platforms[0]. So why not use an interface which is (a) more secure, and (b) platform independent?

[0] http://windows.php.net/

Re: PHPMailer Exploit – Remote Code Execution

#37
post #33
post #24

Earlier quoted context omitted.

That doesn't help - user input is already validated by default in PHPMailer - the problem is that a valid email address can also be an attack string in a shell context, and bugs in PHP make it hard to work around safely.

Really? So you're saying this is a valid e-mail address? "\"Attacker\\' -Param2 -Param3\"@test.com" Let's try it:

filter_var(...) explicitly does not strictly adhere to the RFCs.

And yes, that is, technically, a valid email address:

    "\"Attacker\\' -Param2 -Param3\"@test.com"
gets interpreted by the shell (or by PHP, or by whatever else is responsible for handling backslash-escaped entities in quoted strings) as

    "Attacker\' -Param2 -Param3"@test.com
and "Attacker\' -Param2 -Param3" is a valid local-part: https://tools.ietf.org/html/rfc5321#section-4.1.2

(Email addresses suck and this is not me saying that this is sane.)

Re: PHPMailer Exploit – Remote Code Execution

#39
post #18
post #6

TL;DR: PHPmailer fails to properly sanitize input. When configured to use CLI sendmail, this can lead to arbitrary command execution. But then again, why would you send e-mail to just any address someone enters, without validating it for correctness? I know it is tough to validate all addresses according to RFC, but I'd rather block some legitimate users (which btw. probably know more about RFC than me and I'm sure c…

>I know it is tough to validate all addresses according to RFC Understatement of the year! If you were to try and actually validate according to the RFC, chances are you'll introduce new vectors of attack in your code simply because of the complexity of what you're trying to achieve. Honestly, the email address RFC is a litany of insane choices and kludged-together standards to account for the wild west free-for-all…

That's how I do it. Check for an @. Anything past that is sendmail's problem.

Re: PHPMailer Exploit – Remote Code Execution

#40

Earlier quoted context omitted.

Using command line is the standard way in Linux and de-facto standard in *nix world. "To deliver electronic mail (email), applications shall support the interface provided by sendmail (described here). This interface shall be the default delivery method for applications." http://refspecs.linux-foundation.org/LSB_3.0.0/LSB-PDA/LSB-P...

Yes but PHP runs on non-*NIX platforms[0]. So why not use an interface which is (a) more secure, and (b) platform independent? [0] http://windows.php.net/

Why do anything that makes sense? All I can say about the PHP maintainers' decision process without swearing is that it bewilders me.

Last time I tried configuring a Linux-hosted PHP to do SMTP on localhost:25 instead of shelling out to call sendmail, I found that only Windows builds even have that functionality compiled in. You can apply the same configuration options on a stock Linux build, and they won't cause errors, but they won't do anything, either. Maybe that's changed recently, but it would have to have been very recently, because I ran into this (for the umpteenth time) just a few months ago, while reworking my team's dev environment to allow for examining sent mail without requiring heroism.

I'm not a PHP hater, exactly. I don't like the language at all, but I understand it well and have made a very good living based partly on that knowledge. But the mail story in PHP has never not been a dumpster fire.

Post reply on HN