diff --git a/lib/Service/PhishingDetection/LinkCheck.php b/lib/Service/PhishingDetection/LinkCheck.php index 8b77465317..02f5083d5a 100644 --- a/lib/Service/PhishingDetection/LinkCheck.php +++ b/lib/Service/PhishingDetection/LinkCheck.php @@ -48,6 +48,20 @@ private function parse(string $url): string { return strtolower($url); } + protected function isSuspiciousHost(?string $host): bool { + if ($host === null || $host === '' || !class_exists('\Spoofchecker')) { + return false; + } + + $spoofchecker = new \Spoofchecker(); + + try { + return $spoofchecker->isSuspicious($host); + } catch (\Throwable) { + return false; + } + } + public function run(string $htmlMessage) : PhishingDetectionResult { $results = []; $zippedArray = []; @@ -80,7 +94,9 @@ public function run(string $htmlMessage) : PhishingDetectionResult { $un = new Normalizer($zipped['href']); $url = $un->normalize(); if ($this->textLooksLikeALink($zipped['linkText'])) { - if (parse_url($this->parse($url), PHP_URL_HOST) !== parse_url($this->parse($zipped['linkText']), PHP_URL_HOST)) { + $hrefHost = parse_url($this->parse($url), PHP_URL_HOST); + $linkTextHost = parse_url($this->parse($zipped['linkText']), PHP_URL_HOST); + if ($hrefHost !== $linkTextHost || $this->isSuspiciousHost($hrefHost) || $this->isSuspiciousHost($linkTextHost)) { $results[] = [ 'href' => $url, 'linkText' => $zipped['linkText'], @@ -103,7 +119,7 @@ private function generateResult(array $results): PhishingDetectionResult { return new PhishingDetectionResult( PhishingDetectionResult::LINK_CHECK, true, - $this->l10n->t('Some addresses in this message are not matching the link text'), + $this->l10n->t('Some addresses in this message are suspicious or do not match the link text'), $results ); } diff --git a/tests/Unit/Service/PhishingDetection/LinkCheckTest.php b/tests/Unit/Service/PhishingDetection/LinkCheckTest.php index 85c1cb06e6..e57ac430bc 100644 --- a/tests/Unit/Service/PhishingDetection/LinkCheckTest.php +++ b/tests/Unit/Service/PhishingDetection/LinkCheckTest.php @@ -72,6 +72,20 @@ public function testMultipleLinksOnePhishingReturnsWarning(): void { $this->assertTrue($result->isPhishing()); } + public function testLinkWithSuspiciousMatchingDomainReturnsWarning(): void { + $check = new class($this->l10n) extends LinkCheck { + protected function isSuspiciousHost(?string $host): bool { + return $host === 'xn--pple-43d.com'; + } + }; + + $html = '
https://xn--pple-43d.com'; + + $result = $check->run($html); + + $this->assertTrue($result->isPhishing()); + } + public function testLinkWithBracketsReturnsSafe(): void { $html = '(https://example.com)';