Skip to content

Commit

Permalink
Merge branch 'CVE-2021-34551'
Browse files Browse the repository at this point in the history
# Conflicts:
#	SECURITY.md
#	changelog.md
  • Loading branch information
Synchro committed Jun 16, 2021
2 parents 707205f + 0063f83 commit acd264b
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 21 deletions.
5 changes: 5 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ Please disclose any security issues or vulnerabilities found through [Tidelift's

PHPMailer 6.4.1 and earlier contain a vulnerability that can result in untrusted code being called (if such code is injected into the host project's scope by other means). If the `$patternselect` parameter to `validateAddress()` is set to `'php'` (the default, defined by `static::$validator`), and the global namespace contains a function called `php`, it will be called in preference to the built-in validator of the same name. This is patched in PHPMailer 6.5.0 by denying the use of simple strings as validator function names, which is a very minor BC break. Reported by [Vikrant Singh Chauhan](mailto:vi@hackberry.xyz) via [huntr.dev](https://www.huntr.dev/). Recorded as [CVE-2021-3603](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2021-3603).

PHPMailer versions 6.4.1 and earlier contain a possible remote code execution vulnerability through the `$lang_path` parameter of the `setLanguage()` method. If the `$lang_path` parameter is passed unfiltered from user input, it can be set to [a UNC path](https://docs.microsoft.com/en-us/dotnet/standard/io/file-path-formats#unc-paths), and if an attacker is also able to create a remote mount on the server that the UNC path points to, a script file under their control may be executed. This vulnerability only applies to systems that resolve UNC paths, typically only Microsoft Windows. Recorded as [CVE-2021-34551](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2021-34551). Reported by [listensec.com](https://listensec.com) via Tidelift.

PHPMailer 6.5.0 mitigates this by no longer treating translation files as PHP code, but by parsing their text content directly.
This approach avoids the possibility of executing unknown code while retaining backward compatibility. This isn't ideal, so the current translation format is deprecated and will be replaced in the next major release.

PHPMailer versions between 6.1.8 and 6.4.0 contain a regression of the earlier CVE-2018-19296 object injection vulnerability as a result of [a fix for Windows UNC paths in 6.1.8](https://github.com/PHPMailer/PHPMailer/commit/e2e07a355ee8ff36aba21d0242c5950c56e4c6f9). Recorded as [CVE-2020-36326](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2020-36326). Reported by Fariskhi Vidyan via Tidelift. 6.4.1 fixes this issue, and also enforces stricter checks for URL schemes in local path contexts.

PHPMailer versions 6.1.5 and earlier contain an output escaping bug that occurs in `Content-Type` and `Content-Disposition` when filenames passed into `addAttachment` and other methods that accept attachment names contain double quote characters, in contravention of RFC822 3.4.1. No specific vulnerability has been found relating to this, but it could allow file attachments to bypass attachment filters that are based on matching filename extensions. Recorded as [CVE-2020-13625](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2020-13625). Reported by Elar Lang of Clarified Security.
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6.4.1
6.5.0
4 changes: 4 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# PHPMailer Change Log

## Version 6.5.0 (June 16th, 2021)
* **SECURITY** Fixes CVE-2021-34551, a complex RCE affecting Windows hosts. See [SECURITY.md](SECURITY.md) for details.
* The fix for this issue changes the way that language files are loaded. While they remain in the same PHP-like format, they are processed as plain text, and any code in them will not be run, including operations such as concatenation using the `.` operator.
* *Deprecation* The current translation file format using PHP arrays is now deprecated; the next major version will introduce a new format.
* **SECURITY** Fixes CVE-2021-3603 that may permit untrusted code to be run from an address validator. See [SECURITY.md](SECURITY.md) for details.
* The fix for this issue includes a minor BC break: callables injected into `validateAddress`, or indirectly through the `$validator` class property, may no longer be simple strings. If you want to inject your own validator, provide a closure instead of a function name.

Expand Down
3 changes: 1 addition & 2 deletions language/phpmailer.lang-ar.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
$PHPMAILER_LANG['invalid_address'] = 'الإرسال غير ممكن لأن عنوان البريد الإلكتروني غير صالح: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' برنامج الإرسال غير مدعوم.';
$PHPMAILER_LANG['provide_address'] = 'يجب توفير عنوان البريد الإلكتروني لمستلم واحد على الأقل.';
$PHPMAILER_LANG['recipients_failed'] = 'خطأ SMTP: الأخطاء التالية ' .
'فشل في الارسال لكل من : ';
$PHPMAILER_LANG['recipients_failed'] = 'خطأ SMTP: الأخطاء التالية فشل في الارسال لكل من : ';
$PHPMAILER_LANG['signing'] = 'خطأ في التوقيع: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() غير ممكن.';
$PHPMAILER_LANG['smtp_error'] = 'خطأ على مستوى الخادم SMTP: ';
Expand Down
31 changes: 25 additions & 6 deletions src/PHPMailer.php
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,7 @@ class PHPMailer
*
* @var string
*/
const VERSION = '6.4.1';
const VERSION = '6.5.0';

/**
* Error severity: message only, continue processing.
Expand Down Expand Up @@ -2185,7 +2185,8 @@ public function smtpClose()
* The default language is English.
*
* @param string $langcode ISO 639-1 2-character language code (e.g. French is "fr")
* @param string $lang_path Path to the language file directory, with trailing separator (slash)
* @param string $lang_path Path to the language file directory, with trailing separator (slash).D
* Do not set this from user input!
*
* @return bool
*/
Expand Down Expand Up @@ -2247,14 +2248,32 @@ public function setLanguage($langcode = 'en', $lang_path = '')
if (!static::fileIsAccessible($lang_file)) {
$foundlang = false;
} else {
//Overwrite language-specific strings.
//This way we'll never have missing translation keys.
$foundlang = include $lang_file;
//$foundlang = include $lang_file;
$lines = file($lang_file);
foreach ($lines as $line) {
//Translation file lines look like this:
//$PHPMAILER_LANG['authenticate'] = 'SMTP-Fehler: Authentifizierung fehlgeschlagen.';
//These files are parsed as text and not PHP so as to avoid the possibility of code injection
//See https://blog.stevenlevithan.com/archives/match-quoted-string
$matches = [];
if (
preg_match(
'/^\$PHPMAILER_LANG\[\'([a-z\d_]+)\'\]\s*=\s*(["\'])(.+)*?\2;/',
$line,
$matches
) &&
//Ignore unknown translation keys
array_key_exists($matches[1], $PHPMAILER_LANG)
) {
//Overwrite language-specific strings so we'll never have missing translation keys.
$PHPMAILER_LANG[$matches[1]] = (string)$matches[3];
}
}
}
}
$this->language = $PHPMAILER_LANG;

return (bool) $foundlang; //Returns false if language not found
return $foundlang; //Returns false if language not found
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/POP3.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class POP3
*
* @var string
*/
const VERSION = '6.4.1';
const VERSION = '6.5.0';

/**
* Default POP3 port number.
Expand Down
2 changes: 1 addition & 1 deletion src/SMTP.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class SMTP
*
* @var string
*/
const VERSION = '6.4.1';
const VERSION = '6.5.0';

/**
* SMTP line break constant.
Expand Down
39 changes: 29 additions & 10 deletions test/PHPMailerLangTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ protected function set_up()

/**
* Test language files for missing and excess translations.
* All languages are compared with English.
* All languages are compared with English, which is built-in.
*
* @group languages
*/
Expand All @@ -57,17 +57,36 @@ public function testTranslations()
if (preg_match('/^phpmailer\.lang-([a-z_]{2,})\.php$/', $fileInfo->getFilename(), $matches)) {
$lang = $matches[1]; //Extract language code
$PHPMAILER_LANG = []; //Language strings get put in here
include $fileInfo->getPathname(); //Get language strings
$missing = array_diff(array_keys($definedStrings), array_keys($PHPMAILER_LANG));
$extra = array_diff(array_keys($PHPMAILER_LANG), array_keys($definedStrings));
if (!empty($missing)) {
$err .= "\nMissing translations in $lang: " . implode(', ', $missing);
}
if (!empty($extra)) {
$err .= "\nExtra translations in $lang: " . implode(', ', $extra);
$lines = file($fileInfo->getPathname());
foreach ($lines as $line) {
//Translation file lines look like this:
//$PHPMAILER_LANG['authenticate'] = 'SMTP-Fehler: Authentifizierung fehlgeschlagen.';
//These files are parsed as text and not PHP so as to avoid the possibility of code injection
$matches = [];
if (
preg_match(
'/^\$PHPMAILER_LANG\[\'([a-z\d_]+)\'\]\s*=\s*(["\'])(.+)*?\2;/',
$line,
$matches
)
) {
//Overwrite language-specific strings so we'll never have missing translation keys.
$PHPMAILER_LANG[$matches[1]] = (string)$matches[3];
}
}
}

include $fileInfo->getPathname(); //Get language strings
$missing = array_diff(array_keys($definedStrings), array_keys($PHPMAILER_LANG));
$extra = array_diff(array_keys($PHPMAILER_LANG), array_keys($definedStrings));
if (!empty($missing)) {
$err .= "\nMissing translations in $lang: " . implode(', ', $missing);
}
if (!empty($extra)) {
$err .= "\nExtra translations in $lang: " . implode(', ', $extra);
}
}
$this->assertEmpty($err, $err);
//If we have no extra and no missing translations, $err will be empty
self::assertEmpty($err, $err);
}
}

0 comments on commit acd264b

Please sign in to comment.