
7 changed files with 139 additions and 1 deletions
-
1CHANGELOG
-
7program/actions/mail/index.php
-
24program/actions/mail/show.php
-
64program/lib/Roundcube/rcube_spoofchecker.php
-
1program/localization/en_US/messages.inc
-
2skins/larry/mail.css
-
41tests/Framework/Spoofchecker.php
@ -0,0 +1,64 @@ |
|||
<?php |
|||
|
|||
/** |
|||
+-----------------------------------------------------------------------+ |
|||
| This file is part of the Roundcube Webmail client | |
|||
| | |
|||
| Copyright (C) The Roundcube Dev Team | |
|||
| Copyright (C) Kolab Systems AG | |
|||
| | |
|||
| Licensed under the GNU General Public License version 3 or | |
|||
| any later version with exceptions for skins & plugins. | |
|||
| See the README file for a full license statement. | |
|||
| | |
|||
| PURPOSE: | |
|||
| E-mail/Domain name spoofing detection | |
|||
+-----------------------------------------------------------------------+ |
|||
| Author: Aleksander Machniak <machniak@kolabsys.com> | |
|||
+-----------------------------------------------------------------------+ |
|||
*/ |
|||
|
|||
/** |
|||
* Helper class for spoofing detection. |
|||
* |
|||
* @package Framework |
|||
* @subpackage Utils |
|||
*/ |
|||
class rcube_spoofchecker |
|||
{ |
|||
/** @var array In-memory cache of checked domains */ |
|||
protected static $results = []; |
|||
|
|||
/** |
|||
* Detects (potential) spoofing in an e-mail address or a domain. |
|||
* |
|||
* @param string $domain Email address or domain (UTF8 not punnycode) |
|||
* |
|||
* @return bool True if spoofed/suspicious, False otherwise |
|||
*/ |
|||
public static function check($domain) |
|||
{ |
|||
if (($pos = strrpos($domain, '@')) !== false) { |
|||
$domain = substr($domain, $pos + 1); |
|||
} |
|||
|
|||
if (isset(self::$results[$domain])) { |
|||
return self::$results[$domain]; |
|||
} |
|||
|
|||
// Spoofchecker is part of ext-intl (requires ICU >= 4.2)
|
|||
$checker = new Spoofchecker(); |
|||
|
|||
// Note: The constant (and method?) added in PHP 7.3.0
|
|||
if (defined('Spoofchecker::HIGHLY_RESTRICTIVE')) { |
|||
$checker->setRestrictionLevel(Spoofchecker::HIGHLY_RESTRICTIVE); |
|||
} |
|||
|
|||
$result = $checker->isSuspicious($domain); |
|||
|
|||
// TODO: Use areConfusable() to detect ascii-spoofing of some domains, e.g. paypa1.com?
|
|||
// TODO: Domains with non-printable characters should be considered spoofed
|
|||
|
|||
return self::$results[$domain] = $result; |
|||
} |
|||
} |
@ -0,0 +1,41 @@ |
|||
<?php |
|||
|
|||
/** |
|||
* Test class to test rcube_spoofchecker class |
|||
* |
|||
* @package Tests |
|||
*/ |
|||
class Framework_Spoofchecker extends PHPUnit\Framework\TestCase |
|||
{ |
|||
/** |
|||
* Test data for test_check() |
|||
*/ |
|||
function data_check() |
|||
{ |
|||
return [ |
|||
// Valid:
|
|||
['test@paypal.com', false], |
|||
['postbаnk@gmail.com', false], // ignore spoofed local part
|
|||
['мон.мон', false], |
|||
|
|||
// Suspicious:
|
|||
['test@Рaypal.com', true], |
|||
['test@postbаnk.com', true], |
|||
['aaa.мон', true], |
|||
|
|||
// TODO: Non-working as expected:
|
|||
// ['test@paypa1.com', true],
|
|||
// ['test@paypal' . "\xe2\x80\xa8" . '.com', true],
|
|||
// ['test@paypal' . "\xe2\x80\x8b" . '.com', true],
|
|||
// ['adoḅe.com', true], // ???????
|
|||
]; |
|||
} |
|||
|
|||
/** |
|||
* @dataProvider data_check |
|||
*/ |
|||
function test_check($email, $expected) |
|||
{ |
|||
$this->assertSame($expected, rcube_spoofchecker::check($email)); |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue