1f8369d7dSTobias Sarnowski<?php 2f8369d7dSTobias Sarnowski 3f8369d7dSTobias Sarnowskiclass common_clientIP_test extends DokuWikiTest { 4f8369d7dSTobias Sarnowski 5608cdefcSZebra North /** 6*d5dd5d1bSAndreas Gohr * @var mixed[] $configs Possible values for $conf['trustedproxies']. 7608cdefcSZebra North */ 8608cdefcSZebra North private $configs = [ 9608cdefcSZebra North '^(::1|[fF][eE]80:|127\.|10\.|192\.168\.|172\.((1[6-9])|(2[0-9])|(3[0-1]))\.)', 10608cdefcSZebra North ['::1', 'fe80::/10', '127.0.0.0/8', '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'], 11608cdefcSZebra North ]; 12445b9378SPhy 13a7580321SZebra North /** 14a7580321SZebra North * The data provider for clientIP() tests. 15a7580321SZebra North * 16a7580321SZebra North * @return mixed[][] Returns an array of test cases. 17a7580321SZebra North */ 18a7580321SZebra North public function client_ip_all_provider() : array { 19a7580321SZebra North // Malicious code in a header. 20a7580321SZebra North $bad = '<?php die("hacked"); ?>'; 21a7580321SZebra North 22a7580321SZebra North // Letters A, B, C, D, E will be substitued with an IPv4 or IPv6 address. 23a7580321SZebra North $tests = [ 24a7580321SZebra North // A single IP with no other headers. 25a7580321SZebra North ['A', false, '', '', false, 'A'], 26a7580321SZebra North ['A', true, '', '', false, 'A'], 27a7580321SZebra North ['A', false, '', '', true, 'A'], 28a7580321SZebra North ['A', true, '', '', true, 'A'], 29a7580321SZebra North 30a7580321SZebra North // A X-Real-IP header. 31a7580321SZebra North ['A', false, 'B', '', false, 'A'], 32a7580321SZebra North ['A', true, 'B', '', false, 'B,A'], 33a7580321SZebra North ['A', false, 'B', '', true, 'A'], 34a7580321SZebra North ['A', true, 'B', '', true, 'B'], 35a7580321SZebra North 36a7580321SZebra North // An X-Forwarded-For header from an untrusted proxy. 37a7580321SZebra North ['A', false, 'B', 'C', false, 'A'], 38a7580321SZebra North ['A', true, 'B', 'C', false, 'B,A'], 39a7580321SZebra North ['A', false, 'B', 'C', true, 'A'], 40a7580321SZebra North ['A', true, 'B', 'C', true, 'B'], 41a7580321SZebra North 42a7580321SZebra North // An X-Forwarded-For header from a trusted proxy. 43a7580321SZebra North ['D', false, 'B', 'C', false, 'C,D'], 44a7580321SZebra North ['D', true, 'B', 'C', false, 'B,C,D'], 45a7580321SZebra North ['D', false, 'B', 'C', true, 'C'], 46a7580321SZebra North ['D', true, 'B', 'C', true, 'B'], 47a7580321SZebra North 48a7580321SZebra North // An X-Forwarded-For header with proxies from an untrusted proxy. 49a7580321SZebra North ['A', false, 'B', 'C,E', false, 'A'], 50a7580321SZebra North ['A', true, 'B', 'C,E', false, 'B,A'], 51a7580321SZebra North ['A', false, 'B', 'C,E', true, 'A'], 52a7580321SZebra North ['A', true, 'B', 'C,E', true, 'B'], 53a7580321SZebra North 54608cdefcSZebra North // An X-Forwarded-For header with untrusted proxies from a trusted proxy. 55608cdefcSZebra North ['D', false, 'B', 'C,E', false, 'D'], 56608cdefcSZebra North ['D', true, 'B', 'C,E', false, 'B,D'], 57608cdefcSZebra North ['D', false, 'B', 'C,E', true, 'D'], 58a7580321SZebra North ['D', true, 'B', 'C,E', true, 'B'], 59a7580321SZebra North 60a7580321SZebra North // An X-Forwarded-For header with an invalid proxy from a trusted proxy. 61608cdefcSZebra North ['D', false, 'B', 'C,invalid,E', false, 'D'], 62608cdefcSZebra North ['D', true, 'B', 'C,invalid,E', false, 'B,D'], 63608cdefcSZebra North ['D', false, 'B', 'C,invalid,E', true, 'D'], 64a7580321SZebra North ['D', true, 'B', 'C,invalid,E', true, 'B'], 65a7580321SZebra North 66a7580321SZebra North // Malicious X-Real-IP and X-Forwarded-For headers. 67a7580321SZebra North ['A', false, $bad, $bad, false, 'A'], 68a7580321SZebra North ['A', true, $bad, $bad, false, 'A'], 69a7580321SZebra North ['A', false, $bad, $bad, true, 'A'], 70a7580321SZebra North ['A', true, $bad, $bad, true, 'A'], 71a7580321SZebra North 72a7580321SZebra North // Malicious remote address, X-Real-IP and X-Forwarded-For headers. 73a7580321SZebra North [$bad, false, $bad, $bad, false, '0.0.0.0'], 74a7580321SZebra North [$bad, true, $bad, $bad, false, '0.0.0.0'], 75a7580321SZebra North [$bad, false, $bad, $bad, true, '0.0.0.0'], 76a7580321SZebra North [$bad, true, $bad, $bad, true, '0.0.0.0'], 77a7580321SZebra North ]; 78a7580321SZebra North 79a7580321SZebra North return $tests; 80f8369d7dSTobias Sarnowski } 81f8369d7dSTobias Sarnowski 82a7580321SZebra North /** 83a7580321SZebra North * Test clientIP() with IPv6 addresses. 84a7580321SZebra North * 85a7580321SZebra North * @dataProvider client_ip_all_provider 86a7580321SZebra North * 87a7580321SZebra North * @param string $remoteAddr The TCP/IP remote IP address. 88a7580321SZebra North * @param bool $useRealIp True if using the X-Real-IP header is enabled in the config. 89a7580321SZebra North * @param string $realIp The X-Real-IP header. 90a7580321SZebra North * @param string $forwardedFor The X-Forwarded-For header. 91a7580321SZebra North * @param bool $single True to return the most likely client IP, false to return all candidates. 92a7580321SZebra North * @param string $expected The expected function result. 93a7580321SZebra North * 94a7580321SZebra North * @return void 95a7580321SZebra North */ 96a7580321SZebra North public function test_client_ip_v4(string $remoteAddr, bool $useRealIp, string $realIp, string $forwardedFor, bool $single, string $expected) : void { 97a7580321SZebra North global $conf; 98a7580321SZebra North 99a7580321SZebra North $addresses = [ 100a7580321SZebra North 'A' => '123.123.123.123', 101a7580321SZebra North 'B' => '22.22.22.22', 102a7580321SZebra North 'C' => '33.33.33.33', 103a7580321SZebra North 'D' => '192.168.11.1', 104a7580321SZebra North 'E' => '44.44.44.44', 105a7580321SZebra North ]; 106a7580321SZebra North 107a7580321SZebra North $_SERVER['REMOTE_ADDR'] = str_replace(array_keys($addresses), array_values($addresses), $remoteAddr); 108a7580321SZebra North $_SERVER['HTTP_X_REAL_IP'] = str_replace(array_keys($addresses), array_values($addresses), $realIp); 109a7580321SZebra North $_SERVER['HTTP_X_FORWARDED_FOR'] = str_replace(array_keys($addresses), array_values($addresses), $forwardedFor); 110a7580321SZebra North $conf['realip'] = $useRealIp; 111a7580321SZebra North 112608cdefcSZebra North foreach ($this->configs as $config) { 113*d5dd5d1bSAndreas Gohr $conf['trustedproxies'] = $config; 114a7580321SZebra North $this->assertEquals(str_replace(array_keys($addresses), array_values($addresses), $expected), clientIP($single)); 115f8369d7dSTobias Sarnowski } 116608cdefcSZebra North } 117f8369d7dSTobias Sarnowski 118a7580321SZebra North /** 119a7580321SZebra North * Test clientIP() with IPv6 addresses. 120a7580321SZebra North * 121a7580321SZebra North * @dataProvider client_ip_all_provider 122a7580321SZebra North * 123a7580321SZebra North * @param string $remoteAddr The TCP/IP remote IP address. 124a7580321SZebra North * @param bool $useRealIp True if using the X-Real-IP header is enabled in the config. 125a7580321SZebra North * @param string $realIp The X-Real-IP header. 126a7580321SZebra North * @param string $forwardedFor The X-Forwarded-For header. 127a7580321SZebra North * @param bool $single True to return the most likely client IP, false to return all candidates. 128a7580321SZebra North * @param string $expected The expected function result. 129a7580321SZebra North * 130a7580321SZebra North * @return void 131a7580321SZebra North */ 132a7580321SZebra North public function test_client_ip_v6(string $remoteAddr, bool $useRealIp, string $realIp, string $forwardedFor, bool $single, string $expected) : void { 133a7580321SZebra North global $conf; 134a7580321SZebra North 135a7580321SZebra North $addresses = [ 136a7580321SZebra North 'A' => '1234:1234:1234:1234:1234:1234:1234:1234', 137a7580321SZebra North 'B' => '22:aa:22:bb:22:cc:22:dd', 138a7580321SZebra North 'C' => '33:aa:33:bb:33:cc:33:dd', 139a7580321SZebra North 'D' => '::1', 140a7580321SZebra North 'E' => '44:aa:44:bb:44:cc:44:dd', 141a7580321SZebra North ]; 142a7580321SZebra North 143a7580321SZebra North $_SERVER['REMOTE_ADDR'] = str_replace(array_keys($addresses), array_values($addresses), $remoteAddr); 144a7580321SZebra North $_SERVER['HTTP_X_REAL_IP'] = str_replace(array_keys($addresses), array_values($addresses), $realIp); 145a7580321SZebra North $_SERVER['HTTP_X_FORWARDED_FOR'] = str_replace(array_keys($addresses), array_values($addresses), $forwardedFor); 146a7580321SZebra North $conf['realip'] = $useRealIp; 147a7580321SZebra North 148608cdefcSZebra North foreach ($this->configs as $config) { 149*d5dd5d1bSAndreas Gohr $conf['trustedproxies'] = $config; 150a7580321SZebra North $this->assertEquals(str_replace(array_keys($addresses), array_values($addresses), $expected), clientIP($single)); 151f8369d7dSTobias Sarnowski } 152f8369d7dSTobias Sarnowski } 153608cdefcSZebra North} 154