diff --git a/README.md b/README.md index e5cd9891..85f758d1 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,8 @@ If you don't speak git or just want a tarball, click the 'zip' button on the rig ## Legacy versions PHPMailer 5.2 (which is compatible with PHP 5.0 - 7.0) is no longer being supported for feature updates, and will only be receiving security updates from now on. You will find the latest version of 5.2 in the [5.2-stable branch](https://github.com/PHPMailer/PHPMailer/tree/5.2-stable), and future versions of 5.2 will be tagged with 5.2.x version numbers, so existing Composer configs should remain working. If you're using PHP 5.5 or later, we recommend you make the necessary changes to switch to the 6.0 release. +The 5.2 branch will not receive security updates after December 31st 2018. + ## Upgrading from 5.2 The biggest changes are that source files are now in the `src/` folder, and PHPMailer now declares the namespace `PHPMailer\PHPMailer`. This has several important effects – [read the upgrade guide](https://github.com/PHPMailer/PHPMailer/tree/master/UPGRADING.md) for more details. diff --git a/SECURITY.md b/SECURITY.md index 57a1f136..5e917cd0 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,7 +2,9 @@ Please disclose any vulnerabilities found responsibly - report any security problems found to the maintainers privately. -PHPMailer versions prior to 5.2.24 (released July 26th 2017) have an XSS vulnerability in one of the code examples, [CVE-2017-11503](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-11503). The `code_generator.phps` example did not filter user input prior to output. This file is distributed with a `.phps` extension, so it it not normally executable unless it is explicitly renamed, so it is safe by default. There was also an undisclosed potential XSS vulnerability in the default exception handler (unused by default). Patches for both issues kindly provided by Patrick Monnerat of the Fedora Project. +PHPMailer versions prior to 6.0.6 and 5.2.27 are vulnerable to an object injection attack by passing `phar://` paths into `addAttachment()` and other functions that may receive unfiltered local paths, possibly leading to RCE. Recorded as [CVE-2018-19296](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2018-19296). See [this article](https://knasmueller.net/5-answers-about-php-phar-exploitation) for more info on this type of vulnerability. Mitigated by blocking the use of paths containing URL-protocol style prefixes such as `phar://`. Reported by Sehun Oh of cyberone.kr. + +PHPMailer versions prior to 5.2.24 (released July 26th 2017) have an XSS vulnerability in one of the code examples, [CVE-2017-11503](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-11503). The `code_generator.phps` example did not filter user input prior to output. This file is distributed with a `.phps` extension, so it it not normally executable unless it is explicitly renamed, and the file is not included when PHPMailer is loaded through composer, so it is safe by default. There was also an undisclosed potential XSS vulnerability in the default exception handler (unused by default). Patches for both issues kindly provided by Patrick Monnerat of the Fedora Project. PHPMailer versions prior to 5.2.22 (released January 9th 2017) have a local file disclosure vulnerability, [CVE-2017-5223](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-5223). If content passed into `msgHTML()` is sourced from unfiltered user input, relative paths can map to absolute local file paths and added as attachments. Also note that `addAttachment` (just like `file_get_contents`, `passthru`, `unlink`, etc) should not be passed user-sourced params either! Reported by Yongxiang Li of Asiasecurity. diff --git a/VERSION b/VERSION index 81f0c273..e8738082 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.0.5 \ No newline at end of file +6.0.6 \ No newline at end of file diff --git a/changelog.md b/changelog.md index f7b42273..37e7953d 100644 --- a/changelog.md +++ b/changelog.md @@ -1,7 +1,11 @@ # PHPMailer Change Log +## Version 6.0.6 (November 14th 2018) +* **SECURITY** Fix potential object injection vulnerability. Reported by Sehun Oh of cyberone.kr. * Added Tagalog translation, thanks to @StoneArtz * Added Malagache translation, thanks to @Hackinet +* Updated Serbian translation, fixed incorrect language code, thanks to @mmilanovic4 +* Updated Arabic translations (@MicroDroid) * Updated Hungarian translations * Updated Dutch translations * Updated Slovenian translation (@filips123) @@ -12,7 +16,12 @@ * Add constants for common values, such as `text/html` and `quoted-printable`, and use them * Added support for copied headers in DKIM, helping with debugging, and an option to add extra headers to the DKIM signature. See DKIM_sign example for how to use them. Thanks to @gwi-mmuths. * Add Campaign Monitor transaction ID pattern matcher -* Remove deprecated constant and ini values causing warnings in PHP 7.3. +* Remove deprecated constant and ini values causing warnings in PHP 7.3, added PHP 7.3 build to Travis config. +* Expanded test coverage + +## Version 5.2.27 (November 14th 2018) +* **SECURITY** Fix potential object injection vulnerability. Reported by Sehun Oh of cyberone.kr. +* Note that the 5.2 branch is now deprecated and will not receive security updates after 31st December 2018. ## Version 6.0.5 (March 27th 2018) * Re-roll of 6.0.4 to fix missed version file entry. No code changes. diff --git a/language/phpmailer.lang-rs.php b/language/phpmailer.lang-rs.php deleted file mode 100644 index 0502f021..00000000 --- a/language/phpmailer.lang-rs.php +++ /dev/null @@ -1,26 +0,0 @@ - - */ - -$PHPMAILER_LANG['authenticate'] = 'SMTP грешка: аутентификација није успела.'; -$PHPMAILER_LANG['connect_host'] = 'SMTP грешка: није могуће повезивање са SMTP сервером.'; -$PHPMAILER_LANG['data_not_accepted'] = 'SMTP грешка: подаци нису прихваћени.'; -$PHPMAILER_LANG['empty_message'] = 'Садржај поруке је празан.'; -$PHPMAILER_LANG['encoding'] = 'Непознато кодовање: '; -$PHPMAILER_LANG['execute'] = 'Није могуће извршити наредбу: '; -$PHPMAILER_LANG['file_access'] = 'Није могуће приступити датотеци: '; -$PHPMAILER_LANG['file_open'] = 'Није могуће отворити датотеку: '; -$PHPMAILER_LANG['from_failed'] = 'SMTP грешка: слање са следећих адреса није успело: '; -$PHPMAILER_LANG['recipients_failed'] = 'SMTP грешка: слање на следеће адресе није успело: '; -$PHPMAILER_LANG['instantiate'] = 'Није могуће покренути mail функцију.'; -$PHPMAILER_LANG['invalid_address'] = 'Порука није послата због неисправне адресе: '; -$PHPMAILER_LANG['mailer_not_supported'] = ' мејлер није подржан.'; -$PHPMAILER_LANG['provide_address'] = 'Потребно је задати најмање једну адресу.'; -$PHPMAILER_LANG['signing'] = 'Грешка приликом пријављивања: '; -$PHPMAILER_LANG['smtp_connect_failed'] = 'Повезивање са SMTP сервером није успело.'; -$PHPMAILER_LANG['smtp_error'] = 'Грешка SMTP сервера: '; -$PHPMAILER_LANG['variable_set'] = 'Није могуће задати променљиву, нити је вратити уназад: '; -$PHPMAILER_LANG['extension_missing'] = 'Недостаје проширење: '; diff --git a/language/phpmailer.lang-sr.php b/language/phpmailer.lang-sr.php index b6bfdd0f..34c1e182 100644 --- a/language/phpmailer.lang-sr.php +++ b/language/phpmailer.lang-sr.php @@ -2,6 +2,7 @@ /** * Serbian PHPMailer language file: refer to English translation for definitive list * @package PHPMailer + * @author Александар Јевремовић * @author Miloš Milanović */ diff --git a/src/PHPMailer.php b/src/PHPMailer.php index fd8f1ece..a3be338b 100644 --- a/src/PHPMailer.php +++ b/src/PHPMailer.php @@ -701,7 +701,7 @@ class PHPMailer * * @var string */ - const VERSION = '6.0.5'; + const VERSION = '6.0.6'; /** * Error severity: message only, continue processing. @@ -1471,7 +1471,10 @@ class PHPMailer if (!empty($this->DKIM_domain) and !empty($this->DKIM_selector) and (!empty($this->DKIM_private_string) - or (!empty($this->DKIM_private) and file_exists($this->DKIM_private)) + or (!empty($this->DKIM_private) + and static::isPermittedPath($this->DKIM_private) + and file_exists($this->DKIM_private) + ) ) ) { $header_dkim = $this->DKIM_Add( @@ -1648,6 +1651,20 @@ class PHPMailer return true; } + /** + * Check whether a file path is of a permitted type. + * Used to reject URLs and phar files from functions that access local file paths, + * such as addAttachment. + * + * @param string $path A relative or absolute path to a file + * + * @return bool + */ + protected static function isPermittedPath($path) + { + return !preg_match('#^[a-z]+://#i', $path); + } + /** * Send mail using the PHP mail() function. * @@ -1995,7 +2012,7 @@ class PHPMailer 'dk' => 'da', 'no' => 'nb', 'se' => 'sv', - 'sr' => 'rs', + 'rs' => 'sr', 'tg' => 'tl', ]; @@ -2038,7 +2055,7 @@ class PHPMailer // There is no English translation file if ('en' != $langcode) { // Make sure language file path is readable - if (!file_exists($lang_file)) { + if (!static::isPermittedPath($lang_file) || !file_exists($lang_file)) { $foundlang = false; } else { // Overwrite language-specific strings. @@ -2776,6 +2793,8 @@ class PHPMailer * Add an attachment from a path on the filesystem. * Never use a user-supplied path to a file! * Returns false if the file could not be found or read. + * Explicitly *does not* support passing URLs; PHPMailer is not an HTTP client. + * If you need to do that, fetch the resource yourself and pass it in via a local file or string. * * @param string $path Path to the attachment * @param string $name Overrides the attachment name @@ -2790,7 +2809,7 @@ class PHPMailer public function addAttachment($path, $name = '', $encoding = self::ENCODING_BASE64, $type = '', $disposition = 'attachment') { try { - if (!@is_file($path)) { + if (!static::isPermittedPath($path) || !@is_file($path)) { throw new Exception($this->lang('file_access') . $path, self::STOP_CONTINUE); } @@ -2972,7 +2991,7 @@ class PHPMailer protected function encodeFile($path, $encoding = self::ENCODING_BASE64) { try { - if (!file_exists($path)) { + if (!static::isPermittedPath($path) || !file_exists($path)) { throw new Exception($this->lang('file_open') . $path, self::STOP_CONTINUE); } $file_buffer = file_get_contents($path); @@ -3313,7 +3332,7 @@ class PHPMailer */ public function addEmbeddedImage($path, $cid, $name = '', $encoding = self::ENCODING_BASE64, $type = '', $disposition = 'inline') { - if (!@is_file($path)) { + if (!static::isPermittedPath($path) || !@is_file($path)) { $this->setError($this->lang('file_access') . $path); return false; diff --git a/src/POP3.php b/src/POP3.php index 9b51c8ac..9dab992e 100644 --- a/src/POP3.php +++ b/src/POP3.php @@ -45,7 +45,7 @@ class POP3 * * @var string */ - const VERSION = '6.0.5'; + const VERSION = '6.0.6'; /** * Default POP3 port number. diff --git a/src/SMTP.php b/src/SMTP.php index 6cef06ef..9651e52e 100644 --- a/src/SMTP.php +++ b/src/SMTP.php @@ -34,7 +34,7 @@ class SMTP * * @var string */ - const VERSION = '6.0.5'; + const VERSION = '6.0.6'; /** * SMTP line break constant. diff --git a/test/PHPMailerTest.php b/test/PHPMailerTest.php index 5d2e9926..d3d1e79f 100644 --- a/test/PHPMailerTest.php +++ b/test/PHPMailerTest.php @@ -15,6 +15,7 @@ namespace PHPMailer\Test; use PHPMailer\PHPMailer\OAuth; use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\POP3; +use PHPMailer\PHPMailer\SMTP; use PHPUnit\Framework\TestCase; /** @@ -74,7 +75,7 @@ final class PHPMailerTest extends TestCase include $this->INCLUDE_DIR . '/test/testbootstrap.php'; //Overrides go in here } $this->Mail = new PHPMailer(); - $this->Mail->SMTPDebug = 3; //Full debug output + $this->Mail->SMTPDebug = SMTP::DEBUG_CONNECTION; //Full debug output $this->Mail->Debugoutput = ['PHPMailer\Test\DebugLogTestListener', 'debugLog']; $this->Mail->Priority = 3; $this->Mail->Encoding = '8bit'; @@ -798,6 +799,22 @@ final class PHPMailerTest extends TestCase $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo); } + /** + * Rejection of non-local file attachments test. + */ + public function testRejectNonLocalFileAttachment() + { + $this->assertFalse( + $this->Mail->addAttachment('https://github.com/PHPMailer/PHPMailer/raw/master/README.md'), + 'addAttachment should reject remote URLs' + ); + + $this->assertFalse( + $this->Mail->addAttachment('phar://phar.php'), + 'addAttachment should reject phar resources' + ); + } + /** * Simple plain string attachment test. */ @@ -2506,7 +2523,7 @@ EOT; */ public function testSmtpConnect() { - $this->Mail->SMTPDebug = 4; //Show connection-level errors + $this->Mail->SMTPDebug = SMTP::DEBUG_LOWLEVEL; //Show connection-level errors $this->assertTrue($this->Mail->smtpConnect(), 'SMTP single connect failed'); $this->Mail->smtpClose();