[BUGFIX] Accept Unicode characters in email spam protection 33/59033/8
authorOliver Bartsch <bo@cedev.de>
Tue, 4 Dec 2018 22:50:50 +0000 (23:50 +0100)
committerMarkus Klein <markus.klein@typo3.org>
Mon, 10 Dec 2018 09:30:39 +0000 (10:30 +0100)
Use multibyte handling to properly process all Unicode characters for
the spam protection email address handling.

Resolves: #87071
Releases: master
Change-Id: I9fec60c000a202ae34927ec4917e29e2d0e64a5c
Reviewed-on: https://review.typo3.org/59033
Tested-by: TYPO3com <no-reply@typo3.com>
Tested-by: Joerg Kummer <typo3@enobe.de>
Reviewed-by: Josef Glatz <josef.glatz@typo3.org>
Tested-by: Josef Glatz <josef.glatz@typo3.org>
Reviewed-by: Wittkiel Gruppe <ts@wittkiel-gruppe.com>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Markus Klein <markus.klein@typo3.org>
typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php
typo3/sysext/frontend/Tests/Unit/ContentObject/ContentObjectRendererTest.php

index f86b247..d5ee365 100644 (file)
@@ -5738,14 +5738,13 @@ class ContentObjectRenderer implements LoggerAwareInterface
      * @param mixed  $type - either "ascii" or a number between -10 and 10, taken from config.spamProtectEmailAddresses
      * @return string encoded version of $string
      */
-    protected function encryptEmail($string, $type)
+    protected function encryptEmail(string $string, $type): string
     {
         $out = '';
         // obfuscates using the decimal HTML entity references for each character
         if ($type === 'ascii') {
-            $stringLength = strlen($string);
-            for ($a = 0; $a < $stringLength; $a++) {
-                $out .= '&#' . ord(substr($string, $a, 1)) . ';';
+            foreach (preg_split('//u', $string, -1, PREG_SPLIT_NO_EMPTY) as $char) {
+                $out .= '&#' . mb_ord($char) . ';';
             }
         } else {
             // like str_rot13() but with a variable offset and a wider character range
@@ -5777,14 +5776,13 @@ class ContentObjectRenderer implements LoggerAwareInterface
      * @param mixed  $type - either "ascii" or a number between -10 and 10 taken from config.spamProtectEmailAddresses
      * @return string decoded version of $string
      */
-    protected function decryptEmail($string, $type)
+    protected function decryptEmail(string $string, $type): string
     {
         $out = '';
         // obfuscates using the decimal HTML entity references for each character
         if ($type === 'ascii') {
-            $stringLength = strlen($string);
-            for ($a = 0; $a < $stringLength; $a++) {
-                $out .= '&#' . ord(substr($string, $a, 1)) . ';';
+            foreach (preg_split('//u', $string, -1, PREG_SPLIT_NO_EMPTY) as $char) {
+                $out .= '&#' . mb_ord($char) . ';';
             }
         } else {
             // like str_rot13() but with a variable offset and a wider character range
index dc01283..be2a1f4 100644 (file)
@@ -8216,6 +8216,50 @@ class ContentObjectRendererTest extends UnitTestCase
         $this->assertEquals($value, $this->subject->getUserObjectType());
     }
 
+    /**
+     * Data provider for emailSpamProtectionWithTypeAscii
+     *
+     * @return array [$content, $expect]
+     */
+    public function emailSpamProtectionWithTypeAsciiDataProvider(): array
+    {
+        return [
+            'Simple email address' => [
+                'test@email.tld',
+                '&#116;&#101;&#115;&#116;&#64;&#101;&#109;&#97;&#105;&#108;&#46;&#116;&#108;&#100;'
+            ],
+            'Simple email address with unicode characters' => [
+                'matthäus@email.tld',
+                '&#109;&#97;&#116;&#116;&#104;&#228;&#117;&#115;&#64;&#101;&#109;&#97;&#105;&#108;&#46;&#116;&#108;&#100;'
+            ],
+            'Susceptible email address' => [
+                '"><script>alert(\'emailSpamProtection\')</script>',
+                '&#34;&#62;&#60;&#115;&#99;&#114;&#105;&#112;&#116;&#62;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#101;&#109;&#97;&#105;&#108;&#83;&#112;&#97;&#109;&#80;&#114;&#111;&#116;&#101;&#99;&#116;&#105;&#111;&#110;&#39;&#41;&#60;&#47;&#115;&#99;&#114;&#105;&#112;&#116;&#62;'
+
+            ],
+            'Susceptible email address with unicode characters' => [
+                '"><script>alert(\'ȅmǡilSpamProtȅction\')</script>',
+                '&#34;&#62;&#60;&#115;&#99;&#114;&#105;&#112;&#116;&#62;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#517;&#109;&#481;&#105;&#108;&#83;&#112;&#97;&#109;&#80;&#114;&#111;&#116;&#517;&#99;&#116;&#105;&#111;&#110;&#39;&#41;&#60;&#47;&#115;&#99;&#114;&#105;&#112;&#116;&#62;'
+            ],
+        ];
+    }
+
+    /**
+     * Check if email spam protection processes all UTF-8 characters properly
+     *
+     * @test
+     * @dataProvider emailSpamProtectionWithTypeAsciiDataProvider
+     * @param string $content The parameter $content.
+     * @param string $expected The expected output.
+     */
+    public function mailSpamProtectionWithTypeAscii(string $content, string $expected): void
+    {
+        $this->assertSame(
+            $expected,
+            $this->subject->_call('encryptEmail', $content, 'ascii')
+        );
+    }
+
     /***************************************************************************
      * End: Mixed tests
      ***************************************************************************/