Skip to content

Commit

Permalink
Deny string-based callables altogether
Browse files Browse the repository at this point in the history
  • Loading branch information
Synchro committed Jun 15, 2021
1 parent 6334bab commit 45f3c18
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 10 deletions.
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
8 changes: 2 additions & 6 deletions src/PHPMailer.php
Original file line number Diff line number Diff line change
Expand Up @@ -1337,12 +1337,8 @@ public static function validateAddress($address, $patternselect = null)
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
Expand Down
7 changes: 4 additions & 3 deletions test/PHPMailerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -733,13 +733,14 @@ function ($address) {
'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'));
}

/**
Expand Down

0 comments on commit 45f3c18

Please sign in to comment.