summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorPeter Wilson <peterwilsoncc@git.wordpress.org>2021-05-12 22:33:54 +0000
committerPeter Wilson <peterwilsoncc@git.wordpress.org>2021-05-12 22:33:54 +0000
commitbe35742c0e89aad0d79a4f7d144702d6821be3e3 (patch)
tree63986d5be5f2cbc8ec9e642beeded91f37f360f4
parent91d7ab0f37f86cc28170f8c18a2cb81b4187aa75 (diff)
downloadwordpress-be35742c0e89aad0d79a4f7d144702d6821be3e3.tar.gz
wordpress-be35742c0e89aad0d79a4f7d144702d6821be3e3.zip
External libraries: Improve attachment handling in PHPMailer
Props: audrasjb, ayeshrajans, desrosj, peterwilsoncc, xknown. Partially merges [50799] to the 4.1 branch. git-svn-id: https://develop.svn.wordpress.org/branches/4.1@50863 602fd350-edb4-49c9-b593-d223f7449a82
-rw-r--r--src/wp-includes/class-phpmailer.php54
1 files changed, 46 insertions, 8 deletions
diff --git a/src/wp-includes/class-phpmailer.php b/src/wp-includes/class-phpmailer.php
index 0e48d7269f..4e05a4340b 100644
--- a/src/wp-includes/class-phpmailer.php
+++ b/src/wp-includes/class-phpmailer.php
@@ -1294,9 +1294,12 @@ class PHPMailer
// Sign with DKIM if enabled
if (!empty($this->DKIM_domain)
- && !empty($this->DKIM_selector)
- && (!empty($this->DKIM_private_string)
- || (!empty($this->DKIM_private) && file_exists($this->DKIM_private))
+ and !empty($this->DKIM_selector)
+ and (!empty($this->DKIM_private_string)
+ or (!empty($this->DKIM_private)
+ and self::isPermittedPath($this->DKIM_private)
+ and file_exists($this->DKIM_private)
+ )
)
) {
$header_dkim = $this->DKIM_Add(
@@ -1462,6 +1465,39 @@ class PHPMailer
}
/**
+ * 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)
+ {
+ //Matches scheme definition from https://tools.ietf.org/html/rfc3986#section-3.1
+ return !preg_match('#^[a-z][a-z\d+.-]*://#i', $path);
+ }
+
+ /**
+ * Check whether a file path is safe, accessible, and readable.
+ *
+ * @param string $path A relative or absolute path to a file
+ *
+ * @return bool
+ */
+ protected static function fileIsAccessible($path)
+ {
+ if (!self::isPermittedPath($path)) {
+ return false;
+ }
+ $readable = file_exists($path);
+ //If not a UNC path (expected to start with \\), check read permission, see #2069
+ if (strpos($path, '\\\\') !== 0) {
+ $readable = $readable && is_readable($path);
+ }
+ return $readable;
+ }
+
+ /**
* Send mail using the PHP mail() function.
* @param string $header The message headers
* @param string $body The message body
@@ -1517,7 +1553,7 @@ class PHPMailer
public function getSMTPInstance()
{
if (!is_object($this->smtp)) {
- require_once( 'class-smtp.php' );
+ require_once( 'class-smtp.php' );
$this->smtp = new SMTP;
}
return $this->smtp;
@@ -1784,7 +1820,7 @@ class PHPMailer
// There is no English translation file
if ($langcode != 'en') {
// Make sure language file path is readable
- if (!is_readable($lang_file)) {
+ if (!self::fileIsAccessible($lang_file)) {
$foundlang = false;
} else {
// Overwrite language-specific strings.
@@ -2495,6 +2531,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.
* @param string $encoding File encoding (see $Encoding).
@@ -2506,7 +2544,7 @@ class PHPMailer
public function addAttachment($path, $name = '', $encoding = 'base64', $type = '', $disposition = 'attachment')
{
try {
- if (!@is_file($path)) {
+ if (!self::fileIsAccessible($path)) {
throw new phpmailerException($this->lang('file_access') . $path, self::STOP_CONTINUE);
}
@@ -2687,7 +2725,7 @@ class PHPMailer
protected function encodeFile($path, $encoding = 'base64')
{
try {
- if (!is_readable($path)) {
+ if (!self::fileIsAccessible($path)) {
throw new phpmailerException($this->lang('file_open') . $path, self::STOP_CONTINUE);
}
$magic_quotes = get_magic_quotes_runtime();
@@ -3031,7 +3069,7 @@ class PHPMailer
*/
public function addEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = '', $disposition = 'inline')
{
- if (!@is_file($path)) {
+ if (!self::fileIsAccessible($path)) {
$this->setError($this->lang('file_access') . $path);
return false;
}