aboutsummaryrefslogtreecommitdiffstats
path: root/main/php5-phpmailer/CVE-2016-10033,CVE-2016-10045.patch
blob: 4ade577f202a3f2cfdb640c2b46106402ff46915 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
This patch is based on 2 commits containing fix for CVE-2016-10045 and CVE-2016-10033:
https://github.com/PHPMailer/PHPMailer/commit/9743ff5c7ee16e8d49187bd2e11149afb9485eae
https://github.com/PHPMailer/PHPMailer/commit/833c35fe39715c3d01934508987e97af1fbc1ba0
which were adjusted to PHPMailer_5.2.4 source code

diff -ru PHPMailer_5.2.4/class.phpmailer.php.orig PHPMailer_5.2.4/class.phpmailer.php
--- PHPMailer_5.2.4/class.phpmailer.php.orig
+++ PHPMailer_5.2.4/class.phpmailer.php
@@ -861,6 +861,38 @@
   }
 
   /**
+   * Fix CVE-2016-10033 and CVE-2016-10045 by disallowing potentially unsafe shell characters.
+   *
+   * Note that escapeshellarg and escapeshellcmd are inadequate for our purposes, especially on Windows.
+   * @param string $string The string to be validated
+   * @see https://github.com/PHPMailer/PHPMailer/issues/924 CVE-2016-10045 bug report
+   * @access protected
+   * @return boolean
+   */
+  protected static function isShellSafe($string)
+  {
+      // Future-proof
+      if (escapeshellcmd($string) !== $string or !in_array(escapeshellarg($string), array("'$string'", "\"$string\""))) {
+          return false;
+      }
+
+      $length = strlen($string);
+
+      for ($i = 0; $i < $length; $i++) {
+          $c = $string[$i];
+
+          // All other characters have a special meaning in at least one common shell, including = and +.
+          // Full stop (.) has a special meaning in cmd.exe, but its impact should be negligible here.
+          // Note that this does permit non-Latin alphanumeric characters based on the current locale.
+          if (!ctype_alnum($c) && strpos('@_-.', $c) === false) {
+              return false;
+          }
+      }
+
+      return true;
+  }
+
+  /**
    * Sends mail using the $Sendmail program.
    * @param string $header The message headers
    * @param string $body The message body
@@ -869,8 +901,10 @@
    * @return bool
    */
   protected function SendmailSend($header, $body) {
-    if ($this->Sender != '') {
-      $sendmail = sprintf("%s -oi -f%s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
+    // CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.
+    if (!empty($this->Sender) and self::isShellSafe($this->Sender)) {
+      // TODO: If possible, this should be changed to escapeshellarg.  Needs thorough testing.
+      $sendmail = sprintf("%s -oi -f%s -t", escapeshellcmd($this->Sendmail), $this->Sender);
     } else {
       $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail));
     }
@@ -925,7 +959,9 @@
     if (empty($this->Sender)) {
       $params = "-oi ";
     } else {
-      $params = sprintf("-oi -f%s", $this->Sender);
+      if (self::isShellSafe($this->Sender)) {
+        $params = sprintf("-oi -f%s", $this->Sender);
+      }
     }
     if ($this->Sender != '' and !ini_get('safe_mode')) {
       $old_from = ini_get('sendmail_from');