4 ms·
Per the writeup, it looks like they were already escaping their arguments, but they didn't know PHP's built-in mail() function was already doing that: PHPMa
by jstewartmobile 10y ago
Per the writeup, it looks like they were already escaping their arguments, but they didn't know PHP's built-in mail() function was already doing that:
PHPMailer 5.2.17 sanitizes the $Sender variable
by applying escapeshellarg() escaping before the
value is passed to mail() function.
It does not however take into account the clashing
of the escapeshellarg() function with internal
escaping with escapeshellcmd() performed by mail()
function on the 5th parameter.
As a result it is possible to inject an extra quote
that does not get properly escaped and break out of
the escapeshellarg() protection applied by the patch
in PHPMailer 5.2.17.
In most cases, people are using PHP as a server-side language under a web server. In those cases, it really isn't a good idea to send mail in-process anyway due to web-process and SMTP timeouts. Queueing messages with something like Gearman or some other job handler would be a more secure and performant approach.
- deleted 10y ago[deleted]
- randomdrake 10y ago> It looks like better documentation could have prevented this bug. Where? Barring user-submitted comments, PHP has consistently had some of the most complete programming language documentation. This exact issue is specifically documented with the mail() function[1] so I'm not sure you can blame PHP or ask for better documentation in this case: "This parameter is escaped by escapeshellcmd() internally to prevent command execution. escapeshellcmd() prevents command execution, but allows to add additional parameters. For security reasons, it is recommended for the user to sanitize this parameter to avoid adding unwanted parameters to the shell command." Escaping too many times or incorrectly is a pretty common error but it's normally of the PEBKAC variety. [1] - http://php.net/manual/en/function.mail.php http://php.net/manual/en/function.mail.php
- jstewartmobile 10y agoYou're right. I retract the documentation comment.
- 79d697i6fdif 10y agoWhy is it possible to do command execution in a mailer at all??? Any reasonable language would have abstracted this into an SMTP library where such things are impossible instead of relying on sendmail.
- tyingq 10y agoLikely because PHP has to run things while the end user is waiting for a page to download. They rely on sendmail so that the mail can be queued, versus hanging while the email is sent. PHPmailer can be configured in the way you're describing, but it then has this issue.
- kstrauser 10y agoOpening a socket to a local MTA and dumping a message to it wouldn't take any longer than shelling out to a local sendmail and writing to its stdin.
- deleted 10y ago[deleted]
- tyingq 10y agoThat's true, but it doesn't typically work out of the box. Postfix on debian and ubuntu, for example, won't allow relay through localhost....unless it's sasl authenticated, which requires work. So, yes, you can, but software like Wordpress includes a default configuration that works for most people without additional work...piping to /usr/bin/sendmail.
- skarap 10y ago> In those cases, it really isn't a good idea to send mail in-process anyway due to web-process and SMTP timeouts Why is sending a message to something like RabbitMQ less likely to timeout then to postfix?
- jstewartmobile 10y agoJob queue services have async modes where enqueueing the message returns immediately. Then the jobber can send the message under a more limited account, or even on a different machine in a different language without timeouts. Last I checked, PHP's mail() function blocks until SMTP connect/auth/submit completes, and with things like SMTP tarpitting, or just ordinary slowness, that can take a very long time. Sometimes, it takes more time than your server-side web process is alloted for execution, leading to your script being force-terminated prior to completion. [in reply to skarap] The action of mail() depends on the mail/sendmail settings in your php.ini, so the behavior could be blocking or non-blocking depending on which client is used and which parameters are passed.
- skarap 10y agoThe default configuration for PHP (and I guess the most frequently used one) is using sendmail command. That command does just one thing - enqueue the message on the local server. It doesn't handle the delivery of the email. That is also the case when using the mail server at 127.0.0.1 port 25. One could have configured a remote SMTP server with authentication and that would be slow and would be affected by network issues, but same would happen with a remote RabbitMQ server.
- jstewartmobile 10y agoOn most shared hosts, it blocks. The action taken by mail() is dependent upon your php.ini settings.
- Piskvorrr 10y agoQuite the contrary: most installs I've seen have a "remote" dedicated SMTP server which is actually on local network (not significantly slower than mail()), and does other useful stuff like DKIM and SPF (which, with appropriate setup, has the added bonus that rogue app-server emails don't just appear out of nowhere, and at the very minimum have to pass through this server, giving you a place to debug). Of course, if you're making My First Blog Server on a shared host, then all of this is moot.