Passed
Push — master ( e73618...52f31e )
by Alexander
17:03 queued 10:18
created

EmailTest::testMalformedAddressesIdnEnabled()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 11
cc 2
rs 10
1
<?php
2
3
namespace Yiisoft\Validator\Tests\Rule;
4
5
use PHPUnit\Framework\TestCase;
6
use Yiisoft\Validator\Rule\Email;
7
8
/**
9
 * @group validators
10
 */
11
class EmailTest extends TestCase
12
{
13
    public function testValidate(): void
14
    {
15
        $validator = new Email();
16
17
        $this->assertTrue($validator->validate('[email protected]')->isValid());
18
        $this->assertTrue($validator->validate('[email protected]')->isValid());
19
        $this->assertTrue($validator->validate('[email protected]')->isValid());
20
        $this->assertTrue($validator->validate('user+mailbox/[email protected]')->isValid());
21
        $this->assertTrue($validator->validate('!#$%&\'*+-/=?^_`.{|}[email protected]')->isValid());
22
        $this->assertFalse($validator->validate('rmcreative.ru')->isValid());
23
        $this->assertFalse($validator->validate('Carsten Brandt <[email protected]>')->isValid());
24
        $this->assertFalse($validator->validate('"Carsten Brandt" <[email protected]>')->isValid());
25
        $this->assertFalse($validator->validate('<[email protected]>')->isValid());
26
        $this->assertFalse($validator->validate('info@örtliches.de')->isValid());
27
        $this->assertFalse($validator->validate('sam@рмкреатиф.ru')->isValid());
28
        $this->assertFalse($validator->validate('[email protected]')->isValid());
29
        $this->assertFalse($validator->validate(['[email protected]'])->isValid());
30
31
        $validator->allowName(true);
32
33
        $this->assertTrue($validator->validate('[email protected]')->isValid());
34
        $this->assertTrue($validator->validate('[email protected]')->isValid());
35
        $this->assertFalse($validator->validate('rmcreative.ru')->isValid());
36
        $this->assertTrue($validator->validate('Carsten Brandt <[email protected]>')->isValid());
37
        $this->assertTrue($validator->validate('"Carsten Brandt" <[email protected]>')->isValid());
38
        $this->assertTrue($validator->validate('<[email protected]>')->isValid());
39
        $this->assertFalse($validator->validate('info@örtliches.de')->isValid());
40
        $this->assertFalse($validator->validate('üñîçøðé@üñîçøðé.com')->isValid());
41
        $this->assertFalse($validator->validate('sam@рмкреатиф.ru')->isValid());
42
        $this->assertFalse($validator->validate('Informtation [email protected]')->isValid());
43
        $this->assertTrue($validator->validate('[email protected]')->isValid());
44
        $this->assertTrue($validator->validate('John Smith <[email protected]>')->isValid());
45
        $this->assertTrue($validator->validate('"This name is longer than 64 characters. Blah blah blah blah blah" <[email protected]>')->isValid());
46
        $this->assertFalse($validator->validate('John Smith <example.com>')->isValid());
47
        $this->assertFalse($validator->validate('Short Name <localPartMoreThan64Characters-blah-blah-blah-blah-blah-blah-blah-blah@example.com>')->isValid());
48
        $this->assertFalse($validator->validate('Short Name <domainNameIsMoreThan254Characters@example-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah.com>')->isValid());
49
        $this->assertFalse($validator->validate(['[email protected]'])->isValid());
50
    }
51
52
    public function testValidateIdn(): void
53
    {
54
        if (!function_exists('idn_to_ascii')) {
55
            $this->markTestSkipped('Intl extension required');
56
57
            return;
58
        }
59
        $validator = new Email();
60
        $validator->enableIDN(true);
61
62
        $this->assertTrue($validator->validate('[email protected]')->isValid());
63
        $this->assertTrue($validator->validate('example@äüößìà.de')->isValid());
64
        $this->assertTrue($validator->validate('[email protected]')->isValid());
65
        $this->assertTrue($validator->validate('info@örtliches.de')->isValid());
66
        $this->assertTrue($validator->validate('sam@рмкреатиф.ru')->isValid());
67
        $this->assertTrue($validator->validate('[email protected]')->isValid());
68
        $this->assertTrue($validator->validate('[email protected]')->isValid());
69
        $this->assertTrue($validator->validate('üñîçøðé@üñîçøðé.com')->isValid());
70
        $this->assertFalse($validator->validate('rmcreative.ru')->isValid());
71
        $this->assertFalse($validator->validate('Carsten Brandt <[email protected]>')->isValid());
72
        $this->assertFalse($validator->validate('"Carsten Brandt" <[email protected]>')->isValid());
73
        $this->assertFalse($validator->validate('<[email protected]>')->isValid());
74
75
        $validator->allowName(true);
76
77
        $this->assertTrue($validator->validate('info@örtliches.de')->isValid());
78
        $this->assertTrue($validator->validate('Informtation <info@örtliches.de>')->isValid());
79
        $this->assertFalse($validator->validate('Informtation info@örtliches.de')->isValid());
80
        $this->assertTrue($validator->validate('sam@рмкреатиф.ru')->isValid());
81
        $this->assertTrue($validator->validate('[email protected]')->isValid());
82
        $this->assertTrue($validator->validate('[email protected]')->isValid());
83
        $this->assertFalse($validator->validate('rmcreative.ru')->isValid());
84
        $this->assertTrue($validator->validate('Carsten Brandt <[email protected]>')->isValid());
85
        $this->assertTrue($validator->validate('"Carsten Brandt" <[email protected]>')->isValid());
86
        $this->assertTrue($validator->validate('üñîçøðé 日本国 <üñîçøðé@üñîçøðé.com>')->isValid());
87
        $this->assertTrue($validator->validate('<[email protected]>')->isValid());
88
        $this->assertTrue($validator->validate('[email protected]')->isValid());
89
        $this->assertTrue($validator->validate('John Smith <[email protected]>')->isValid());
90
        $this->assertTrue($validator->validate('"Такое имя достаточно длинное, но оно все равно может пройти валидацию" <[email protected]>')->isValid());
91
        $this->assertFalse($validator->validate('John Smith <example.com>')->isValid());
92
        $this->assertFalse($validator->validate('Короткое имя <после-преобразования-в-idn-тут-будет-больше-чем-64-символа@пример.com>')->isValid());
93
        $this->assertFalse($validator->validate('Короткое имя <тест@это-доменное-имя.после-преобразования-в-idn.будет-содержать-больше-254-символов.бла-бла-бла-бла-бла-бла-бла-бла.бла-бла-бла-бла-бла-бла.бла-бла-бла-бла-бла-бла.бла-бла-бла-бла-бла-бла.com>')->isValid());
94
    }
95
96
    public function testValidateMx(): void
97
    {
98
        $this->markTestSkipped('Too slow :(');
99
100
        $validator = new Email();
101
102
        $validator->checkDNS(true);
103
        $this->assertTrue($validator->validate('[email protected]')->isValid());
104
105
        $validator->checkDNS(false);
106
        $this->assertTrue($validator->validate('[email protected]')->isValid());
107
        $validator->checkDNS(true);
108
        $this->assertFalse($validator->validate('[email protected]')->isValid());
109
110
        $validator->checkDns(true);
111
        $validator->allowName(true);
112
        $emails = [
113
            '[email protected]',
114
            'Ivan Petrov <[email protected]>',
115
        ];
116
        foreach ($emails as $email) {
117
            $this->assertTrue($validator->validate($email)->isValid(),
118
                "Email: '$email' failed to validate(checkDNS=true, allowName=true)");
119
        }
120
    }
121
122
    public function malformedAddressesProvider(): array
123
    {
124
        return [
125
            // this is the demo email used in the proof of concept of the exploit
126
            ['"attacker\" -oQ/tmp/ -X/var/www/cache/phpcode.php "@email.com'],
127
            // trying more adresses
128
            ['"Attacker -Param2 -Param3"@test.com'],
129
            ['\'Attacker -Param2 -Param3\'@test.com'],
130
            ['"Attacker \" -Param2 -Param3"@test.com'],
131
            ["'Attacker \\' -Param2 -Param3'@test.com"],
132
            ['"attacker\" -oQ/tmp/ -X/var/www/cache/phpcode.php "@email.com'],
133
            // and even more variants
134
            ['"attacker\"\ -oQ/tmp/\ -X/var/www/cache/phpcode.php"@email.com'],
135
            ["\"attacker\\\"\0-oQ/tmp/\0-X/var/www/cache/phpcode.php\"@email.com"],
136
            ['"[email protected]\"-Xbeep"@email.com'],
137
138
            ["'attacker\\' -oQ/tmp/ -X/var/www/cache/phpcode.php'@email.com"],
139
            ["'attacker\\\\' -oQ/tmp/ -X/var/www/cache/phpcode.php'@email.com"],
140
            ["'attacker\\\\'\\ -oQ/tmp/ -X/var/www/cache/phpcode.php'@email.com"],
141
            ["'attacker\\';touch /tmp/hackme'@email.com"],
142
            ["'attacker\\\\';touch /tmp/hackme'@email.com"],
143
            ["'attacker\\';touch/tmp/hackme'@email.com"],
144
            ["'attacker\\\\';touch/tmp/hackme'@email.com"],
145
            ['"attacker\" -oQ/tmp/ -X/var/www/cache/phpcode.php "@email.com'],
146
        ];
147
    }
148
149
    /**
150
     * Test malicious email addresses that can be used to exploit SwiftMailer vulnerability CVE-2016-10074 while IDN is
151
     * disabled.
152
     * @see https://legalhackers.com/advisories/SwiftMailer-Exploit-Remote-Code-Exec-CVE-2016-10074-Vuln.html
153
     * @dataProvider malformedAddressesProvider
154
     *
155
     * @param string $value
156
     */
157
    public function testMalformedAddressesIdnDisabled($value): void
158
    {
159
        $validator = new Email();
160
        $validator->enableIDN(true);
161
        $this->assertFalse($validator->validate($value)->isValid());
162
    }
163
164
    /**
165
     * Test malicious email addresses that can be used to exploit SwiftMailer vulnerability CVE-2016-10074 while IDN is
166
     * enabled.
167
     * @see https://legalhackers.com/advisories/SwiftMailer-Exploit-Remote-Code-Exec-CVE-2016-10074-Vuln.html
168
     * @dataProvider malformedAddressesProvider
169
     *
170
     * @param string $value
171
     */
172
    public function testMalformedAddressesIdnEnabled($value): void
173
    {
174
        if (!function_exists('idn_to_ascii')) {
175
            $this->markTestSkipped('Intl extension required');
176
177
            return;
178
        }
179
180
        $val = new Email();
181
        $val->enableIDN(true);
182
        $this->assertFalse($val->validate($value)->isValid());
183
    }
184
}
185