CVE-2021-3603 (published 2021-06-17T12:15Z)

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 PHPMailer::$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. Mitigated in PHPMailer 6.5.0 by denying the use of simple strings as validator function names.

Severity: MEDIUM
CVSS v2 base score: 6.8 (AV:N/AC:M/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 8.1, HIGH (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-829
cwe_name: Inclusion of Functionality from Untrusted Control Sphere
description: The product imports, requires, or includes executable functionality (such as a library) from a source that is outside of the intended control sphere.
extended_description: 
            When including third-party functionality, such as a web widget, library, or other source of functionality, the product must effectively trust that functionality. Without sufficient protection mechanisms, the functionality could be malicious in nature (either by coming from an untrusted source, being spoofed, or being modified in transit from a trusted source). The functionality might also contain its own weaknesses, or grant access to additional functionality and state information that should be kept private to the base system, such as system state information, sensitive application data, or the DOM of a web application.
            This might lead to many different consequences depending on the included functionality, but some examples include injection of malware, information exposure by granting excessive privileges or permissions to the untrusted functionality, DOM-based XSS vulnerabilities, stealing user's cookies, or open redirect to malware (CWE-601).
         
         

Fix information:
repo_url: https://github.com/PHPMailer/PHPMailer
commit_details: repo_url: https://github.com/PHPMailer/PHPMailer
author: Marcus Bointon
author_date: 2021-06-15 17:37:24+02:00
msg: Deny string-based callables altogether
repository: repo_url: https://github.com/PHPMailer/PHPMailer
repo_name: PHPMailer/PHPMailer
description: The classic email sending library for PHP
repo_language: PHP
owner: PHPMailer
file_changes: filename: SECURITY.md
change_type: ModificationType.MODIFY
diff: @@ -2,7 +2,7 @@
 
 Please disclose any security issues or vulnerabilities found through [Tidelift's coordinated disclosure system](https://tidelift.com/security) or to the maintainers privately.
 
-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 callables with the same names as built-in validators. 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 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 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.
 

programming_language: Markdown
filename: PHPMailer.php
change_type: ModificationType.MODIFY
diff: @@ -1337,12 +1337,8 @@ class PHPMailer
         if (null === $patternselect) {
             $patternselect = static::$validator;
         }
-        //Don't allow overriding built-in validators with callables
-        if (
-            is_callable($patternselect) &&
-            //It's callable and not a string, or it's a string callable that's not a built-in pattern
-            (!is_string($patternselect) || !in_array(strtolower($patternselect), ['php', 'pcre', 'pcre8', 'html5']))
-        ) {
+        //Don't allow strings as callables, see SECURITY.md and CVE-2021-3603
+        if (is_callable($patternselect) && !is_string($patternselect)) {
             return call_user_func($patternselect, $address);
         }
         //Reject line breaks in addresses; it's valid RFC5322, but not RFC5321

programming_language: PHP
filename: PHPMailerTest.php
change_type: ModificationType.MODIFY
diff: @@ -733,13 +733,14 @@ final class PHPMailerTest extends TestCase
             'PHP validator not behaving as expected'
         );
 
-        //Test denying override of built-in validator names
+        //Test denying function name callables as validators
         //See SECURITY.md and CVE-2021-3603
         //If a `php` function defined in validators.php successfully overrides this built-in validator name,
         //this would return false – and we don't want to allow that
         self::assertTrue(PHPMailer::validateAddress('test@example.com', 'php'));
-        //Check a non-matching validator function, which should be permitted, and return false in this case
-        self::assertFalse(PHPMailer::validateAddress('test@example.com', 'phpx'));
+        //Check that a non-existent validator name falls back to a built-in validator
+        //and does not call a global function with that name
+        self::assertTrue(PHPMailer::validateAddress('test@example.com', 'phpx'));
     }
 
     /**

programming_language: PHP