mirror of
https://github.com/roundcube/roundcubemail.git
synced 2025-12-27 23:45:58 +00:00
Show homograph-warning-icon before email address, unify warning wording
Some checks are pending
E2E / Linux / PHP ${{ matrix.php }} (8.1) (push) Waiting to run
E2E / Linux / PHP ${{ matrix.php }} (8.3) (push) Waiting to run
E2E / Linux / PHP ${{ matrix.php }} (8.5) (push) Waiting to run
CI / Coding Style (push) Waiting to run
CI / Static Analysis (push) Waiting to run
Message Rendering / Linux / PHP ${{ matrix.php }} (8.3) (push) Waiting to run
Message Rendering / Linux / PHP ${{ matrix.php }} (8.4) (push) Waiting to run
Message Rendering / Linux / PHP ${{ matrix.php }} (8.5) (push) Waiting to run
Unit / Linux / PHP ${{ matrix.php }} (8.1) (push) Waiting to run
Unit / Linux / PHP ${{ matrix.php }} (8.2) (push) Waiting to run
Unit / Linux / PHP ${{ matrix.php }} (8.3) (push) Waiting to run
Unit / Linux / PHP ${{ matrix.php }} (8.4) (push) Waiting to run
Unit / Linux / PHP ${{ matrix.php }} (8.5) (push) Waiting to run
Unit / Windows / PHP ${{ matrix.php }} (8.1) (push) Waiting to run
Unit / Windows / PHP ${{ matrix.php }} (8.2) (push) Waiting to run
Unit / Windows / PHP ${{ matrix.php }} (8.3) (push) Waiting to run
Unit / Windows / PHP ${{ matrix.php }} (8.4) (push) Waiting to run
Unit / Windows / PHP ${{ matrix.php }} (8.5) (push) Waiting to run
Some checks are pending
E2E / Linux / PHP ${{ matrix.php }} (8.1) (push) Waiting to run
E2E / Linux / PHP ${{ matrix.php }} (8.3) (push) Waiting to run
E2E / Linux / PHP ${{ matrix.php }} (8.5) (push) Waiting to run
CI / Coding Style (push) Waiting to run
CI / Static Analysis (push) Waiting to run
Message Rendering / Linux / PHP ${{ matrix.php }} (8.3) (push) Waiting to run
Message Rendering / Linux / PHP ${{ matrix.php }} (8.4) (push) Waiting to run
Message Rendering / Linux / PHP ${{ matrix.php }} (8.5) (push) Waiting to run
Unit / Linux / PHP ${{ matrix.php }} (8.1) (push) Waiting to run
Unit / Linux / PHP ${{ matrix.php }} (8.2) (push) Waiting to run
Unit / Linux / PHP ${{ matrix.php }} (8.3) (push) Waiting to run
Unit / Linux / PHP ${{ matrix.php }} (8.4) (push) Waiting to run
Unit / Linux / PHP ${{ matrix.php }} (8.5) (push) Waiting to run
Unit / Windows / PHP ${{ matrix.php }} (8.1) (push) Waiting to run
Unit / Windows / PHP ${{ matrix.php }} (8.2) (push) Waiting to run
Unit / Windows / PHP ${{ matrix.php }} (8.3) (push) Waiting to run
Unit / Windows / PHP ${{ matrix.php }} (8.4) (push) Waiting to run
Unit / Windows / PHP ${{ matrix.php }} (8.5) (push) Waiting to run
This moves the warning icon that is triggered by the homograph check from the generic "notification area" (between headers and body) to the header area, before the address that the warning is referring to. The previous warning left it unclear which address was found to be problematic, which now is obvious. Additionally there's now a test to check for these warnings to show up in the DOM.
This commit is contained in:
parent
f76cace186
commit
8eeedc0c8c
@ -1380,10 +1380,11 @@ class rcmail_action_mail_index extends rcmail_action
|
||||
}
|
||||
$mailto = rcube_utils::idn_to_utf8($mailto);
|
||||
|
||||
// Homograph attack detection (#6891)
|
||||
if ($spoofcheck && !self::$SUSPICIOUS_EMAIL) {
|
||||
self::$SUSPICIOUS_EMAIL = rcube_spoofchecker::check($mailto);
|
||||
}
|
||||
// Homograph attack detection (#6891),
|
||||
// and phishing email prevention (#1488981) (e.g. "valid@email.addr <phishing@email.addr>")
|
||||
$show_fraud_warning = $spoofcheck
|
||||
&& !self::$PRINT_MODE // Don't show the warning in print mode, because there's no danger of interaction.
|
||||
&& (rcube_spoofchecker::check($mailto) || ($name && $name != $mailto && preg_match('/@|@|﹫/', $name)));
|
||||
|
||||
if (self::$PRINT_MODE) {
|
||||
$address = '<' . rcube::Q($mailto) . '>';
|
||||
@ -1398,26 +1399,16 @@ class rcmail_action_mail_index extends rcmail_action
|
||||
'onclick' => sprintf("return %s.command('compose','%s',this)",
|
||||
rcmail_output::JS_OBJECT_NAME, rcube::JQ(format_email_recipient($mailto, $name))),
|
||||
];
|
||||
$prefix = '';
|
||||
|
||||
if ($name && $name != $mailto && preg_match('/@|@|﹫/', $name)) {
|
||||
// phishing email prevention (#1488981), e.g. "valid@email.addr <phishing@email.addr>"
|
||||
$content = rcube::SQ(sprintf('%s <%s>', $name, $mailto));
|
||||
$msg = $rcmail->gettext('senderphishingwarning');
|
||||
$prefix = html::span([
|
||||
'class' => 'sender-phishing-warning',
|
||||
'title' => $msg,
|
||||
'role' => 'img',
|
||||
'aria-label' => $msg,
|
||||
], '');
|
||||
} elseif ($show_email && $name && $mailto) {
|
||||
// In case of a fraud warning always show all details, regardless of the config.
|
||||
if ($show_fraud_warning || ($show_email && $name && $mailto)) {
|
||||
$content = rcube::SQ(sprintf('%s <%s>', $name, $mailto));
|
||||
} else {
|
||||
$content = rcube::SQ($name ?: $mailto);
|
||||
$attrs['title'] = $mailto;
|
||||
}
|
||||
|
||||
$address = $prefix . html::a($attrs, $content);
|
||||
$address = html::a($attrs, $content);
|
||||
} else {
|
||||
$address = html::span(['title' => $mailto, 'class' => 'rcmContactAddress'],
|
||||
rcube::SQ($name ?: $mailto));
|
||||
@ -1447,6 +1438,18 @@ class rcmail_action_mail_index extends rcmail_action
|
||||
}
|
||||
}
|
||||
|
||||
if ($show_fraud_warning) {
|
||||
// $content = rcube::SQ(sprintf('%s <%s>', $name, $mailto));
|
||||
$msg = $rcmail->gettext('suspiciousemail');
|
||||
$prefix = html::span([
|
||||
'class' => 'suspicious-address-warning',
|
||||
'title' => $msg,
|
||||
'role' => 'img',
|
||||
'aria-label' => $msg,
|
||||
], '');
|
||||
$address = $prefix . $address;
|
||||
}
|
||||
|
||||
$address = html::span('adr', $address);
|
||||
$allvalues[] = $address;
|
||||
|
||||
|
||||
@ -283,29 +283,6 @@ class rcmail_action_mail_show extends rcmail_action_mail_index
|
||||
return html::div($attrib, $msg . ' ' . html::span('boxbuttons', $buttons));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a warning whenever a suspicious email address has been found in the message.
|
||||
*
|
||||
* @return string HTML content of the warning element
|
||||
*/
|
||||
public static function suspicious_content_warning()
|
||||
{
|
||||
if (empty(self::$SUSPICIOUS_EMAIL)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$rcmail = rcmail::get_instance();
|
||||
|
||||
$attrib = [
|
||||
'id' => 'suspicious-content-message',
|
||||
'class' => 'notice',
|
||||
];
|
||||
|
||||
$msg = html::span(null, rcube::Q($rcmail->gettext('suspiciousemail')));
|
||||
|
||||
return html::div($attrib, $msg);
|
||||
}
|
||||
|
||||
public static function message_buttons()
|
||||
{
|
||||
$rcmail = rcmail::get_instance();
|
||||
@ -352,7 +329,6 @@ class rcmail_action_mail_show extends rcmail_action_mail_index
|
||||
$content = [
|
||||
self::message_buttons(),
|
||||
self::remote_objects_msg(),
|
||||
self::suspicious_content_warning(),
|
||||
];
|
||||
|
||||
$plugin = $rcmail->plugins->exec_hook('message_objects',
|
||||
|
||||
@ -233,4 +233,3 @@ $messages['emptyattachment'] = 'This attachment appears to be empty.<br>Please,
|
||||
$messages['oauthloginfailed'] = 'OAuth login failed. Please try again.';
|
||||
$messages['oauthinvalidrequest'] = 'Authorization request was invalid or incomplete.';
|
||||
$messages['oauthaccessdenied'] = 'Authorization server or the user denied the request.';
|
||||
$messages['senderphishingwarning'] = 'This sender name and address look forged, please be careful!';
|
||||
|
||||
@ -434,7 +434,7 @@ body.task-error-login #layout {
|
||||
margin: 1rem 1rem 0 1rem;
|
||||
}
|
||||
|
||||
.sender-phishing-warning:before {
|
||||
.suspicious-address-warning:before {
|
||||
.font-icon-class();
|
||||
float: none;
|
||||
display: inline-block;
|
||||
|
||||
28
tests/MessageRendering/EmailAdressSpoofingAttacksTest.php
Normal file
28
tests/MessageRendering/EmailAdressSpoofingAttacksTest.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\MessageRendering;
|
||||
|
||||
/**
|
||||
* Test class to test simple messages.
|
||||
*/
|
||||
class EmailAdressSpoofingAttacksTest extends MessageRenderingTestCase
|
||||
{
|
||||
/**
|
||||
* Test that two text mime-parts with disposition "attachment" are shown as
|
||||
* attachments.
|
||||
*/
|
||||
public function testEmailAdressSpoofingAttacks()
|
||||
{
|
||||
$domxpath = $this->runAndGetHtmlOutputDomxpath('1176148a1ed73947311a08a3fc11264e64d8f775eae596e5fa660cfd1684a5e6@example.net');
|
||||
$this->assertSame('Email address spoofing attacks', $this->getScrubbedSubject($domxpath));
|
||||
|
||||
$suspiciousAddressWarnings = $domxpath->query('//span[@class="suspicious-address-warning"]');
|
||||
// It should be present three times: two times for the phishing attack in the From header (once in the header
|
||||
// summary element, once in the header details element), one time for the homograph attack in the To header.
|
||||
$this->assertCount(3, $suspiciousAddressWarnings, 'Sender phishing warning');
|
||||
$expectedMsg = 'This message contains suspicious email addresses that may be fraudulent.';
|
||||
$this->assertSame($expectedMsg, $suspiciousAddressWarnings[0]->attributes->getNamedItem('title')->textContent);
|
||||
$this->assertSame($expectedMsg, $suspiciousAddressWarnings[1]->attributes->getNamedItem('title')->textContent);
|
||||
$this->assertSame($expectedMsg, $suspiciousAddressWarnings[2]->attributes->getNamedItem('title')->textContent);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
From: "Someone" <valid@example.net>:<attacker@example.org>
|
||||
To: test@Рaypal.com
|
||||
Subject: Email address spoofing attacks
|
||||
MIME-Version: 1.0
|
||||
Date: Fri, 12 June 2025 23:42:00 +0200
|
||||
Message-ID: <1176148a1ed73947311a08a3fc11264e64d8f775eae596e5fa660cfd1684a5e6@example.net>
|
||||
Content-Type: text/plain
|
||||
|
||||
The content doesn't really matter.
|
||||
Loading…
Reference in New Issue
Block a user