diff options
Diffstat (limited to '_test/tests/inc/common_clientip.test.php')
-rw-r--r-- | _test/tests/inc/common_clientip.test.php | 356 |
1 files changed, 142 insertions, 214 deletions
diff --git a/_test/tests/inc/common_clientip.test.php b/_test/tests/inc/common_clientip.test.php index 212d8cfbc..4375ad921 100644 --- a/_test/tests/inc/common_clientip.test.php +++ b/_test/tests/inc/common_clientip.test.php @@ -2,224 +2,152 @@ class common_clientIP_test extends DokuWikiTest { - function setup() : void { - parent::setup(); - + /** + * @var mixed[] $configs Possible values for $conf['trustedproxy']. + */ + private $configs = [ + '^(::1|[fF][eE]80:|127\.|10\.|192\.168\.|172\.((1[6-9])|(2[0-9])|(3[0-1]))\.)', + ['::1', 'fe80::/10', '127.0.0.0/8', '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'], + ]; + + /** + * The data provider for clientIP() tests. + * + * @return mixed[][] Returns an array of test cases. + */ + public function client_ip_all_provider() : array { + // Malicious code in a header. + $bad = '<?php die("hacked"); ?>'; + + // Letters A, B, C, D, E will be substitued with an IPv4 or IPv6 address. + $tests = [ + // A single IP with no other headers. + ['A', false, '', '', false, 'A'], + ['A', true, '', '', false, 'A'], + ['A', false, '', '', true, 'A'], + ['A', true, '', '', true, 'A'], + + // A X-Real-IP header. + ['A', false, 'B', '', false, 'A'], + ['A', true, 'B', '', false, 'B,A'], + ['A', false, 'B', '', true, 'A'], + ['A', true, 'B', '', true, 'B'], + + // An X-Forwarded-For header from an untrusted proxy. + ['A', false, 'B', 'C', false, 'A'], + ['A', true, 'B', 'C', false, 'B,A'], + ['A', false, 'B', 'C', true, 'A'], + ['A', true, 'B', 'C', true, 'B'], + + // An X-Forwarded-For header from a trusted proxy. + ['D', false, 'B', 'C', false, 'C,D'], + ['D', true, 'B', 'C', false, 'B,C,D'], + ['D', false, 'B', 'C', true, 'C'], + ['D', true, 'B', 'C', true, 'B'], + + // An X-Forwarded-For header with proxies from an untrusted proxy. + ['A', false, 'B', 'C,E', false, 'A'], + ['A', true, 'B', 'C,E', false, 'B,A'], + ['A', false, 'B', 'C,E', true, 'A'], + ['A', true, 'B', 'C,E', true, 'B'], + + // An X-Forwarded-For header with untrusted proxies from a trusted proxy. + ['D', false, 'B', 'C,E', false, 'D'], + ['D', true, 'B', 'C,E', false, 'B,D'], + ['D', false, 'B', 'C,E', true, 'D'], + ['D', true, 'B', 'C,E', true, 'B'], + + // An X-Forwarded-For header with an invalid proxy from a trusted proxy. + ['D', false, 'B', 'C,invalid,E', false, 'D'], + ['D', true, 'B', 'C,invalid,E', false, 'B,D'], + ['D', false, 'B', 'C,invalid,E', true, 'D'], + ['D', true, 'B', 'C,invalid,E', true, 'B'], + + // Malicious X-Real-IP and X-Forwarded-For headers. + ['A', false, $bad, $bad, false, 'A'], + ['A', true, $bad, $bad, false, 'A'], + ['A', false, $bad, $bad, true, 'A'], + ['A', true, $bad, $bad, true, 'A'], + + // Malicious remote address, X-Real-IP and X-Forwarded-For headers. + [$bad, false, $bad, $bad, false, '0.0.0.0'], + [$bad, true, $bad, $bad, false, '0.0.0.0'], + [$bad, false, $bad, $bad, true, '0.0.0.0'], + [$bad, true, $bad, $bad, true, '0.0.0.0'], + ]; + + return $tests; + } + + /** + * Test clientIP() with IPv6 addresses. + * + * @dataProvider client_ip_all_provider + * + * @param string $remoteAddr The TCP/IP remote IP address. + * @param bool $useRealIp True if using the X-Real-IP header is enabled in the config. + * @param string $realIp The X-Real-IP header. + * @param string $forwardedFor The X-Forwarded-For header. + * @param bool $single True to return the most likely client IP, false to return all candidates. + * @param string $expected The expected function result. + * + * @return void + */ + public function test_client_ip_v4(string $remoteAddr, bool $useRealIp, string $realIp, string $forwardedFor, bool $single, string $expected) : void { global $conf; - $conf['trustedproxy'] = '^(::1|[fF][eE]80:|127\.|10\.|192\.168\.|172\.((1[6-9])|(2[0-9])|(3[0-1]))\.)'; - } - - function test_simple_all(){ - $_SERVER['REMOTE_ADDR'] = '123.123.123.123'; - $_SERVER['HTTP_X_REAL_IP'] = ''; - $_SERVER['HTTP_X_FORWARDED_FOR'] = ''; - $out = '123.123.123.123'; - $this->assertEquals($out, clientIP()); - } - - function test_proxy1_all(){ - $_SERVER['REMOTE_ADDR'] = '123.123.123.123'; - $_SERVER['HTTP_X_REAL_IP'] = '77.77.77.77'; - $_SERVER['HTTP_X_FORWARDED_FOR'] = ''; - $out = '123.123.123.123,77.77.77.77'; - $this->assertEquals($out, clientIP()); - } - - function test_proxy2_all(){ - $_SERVER['REMOTE_ADDR'] = '123.123.123.123'; - $_SERVER['HTTP_X_REAL_IP'] = ''; - $_SERVER['HTTP_X_FORWARDED_FOR'] = '77.77.77.77'; - $out = '123.123.123.123,77.77.77.77'; - $this->assertEquals($out, clientIP()); - } - - function test_proxyhops_all(){ - $_SERVER['REMOTE_ADDR'] = '123.123.123.123'; - $_SERVER['HTTP_X_REAL_IP'] = ''; - $_SERVER['HTTP_X_FORWARDED_FOR'] = '77.77.77.77,66.66.66.66'; - $out = '123.123.123.123,77.77.77.77,66.66.66.66'; - $this->assertEquals($out, clientIP()); - } - - function test_simple_single(){ - $_SERVER['REMOTE_ADDR'] = '123.123.123.123'; - $_SERVER['HTTP_X_REAL_IP'] = ''; - $_SERVER['HTTP_X_FORWARDED_FOR'] = ''; - $out = '123.123.123.123'; - $this->assertEquals($out, clientIP(true)); - } - - function test_proxy1_single(){ - $_SERVER['REMOTE_ADDR'] = '123.123.123.123'; - $_SERVER['HTTP_X_REAL_IP'] = '77.77.77.77'; - $_SERVER['HTTP_X_FORWARDED_FOR'] = ''; - $out = '123.123.123.123'; - $this->assertEquals($out, clientIP(true)); - } - - function test_proxy2_single(){ - $_SERVER['REMOTE_ADDR'] = '123.123.123.123'; - $_SERVER['HTTP_X_REAL_IP'] = ''; - $_SERVER['HTTP_X_FORWARDED_FOR'] = '77.77.77.77'; - $out = '123.123.123.123'; - $this->assertEquals($out, clientIP(true)); - } - - function test_proxyhops_single(){ - $_SERVER['REMOTE_ADDR'] = '123.123.123.123'; - $_SERVER['HTTP_X_REAL_IP'] = ''; - $_SERVER['HTTP_X_FORWARDED_FOR'] = '77.77.77.77,66.66.66.66'; - $out = '123.123.123.123'; - $this->assertEquals($out, clientIP(true)); - } - - function test_proxy1_local_single(){ - $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; - $_SERVER['HTTP_X_REAL_IP'] = '77.77.77.77'; - $_SERVER['HTTP_X_FORWARDED_FOR'] = ''; - $out = '77.77.77.77'; - $this->assertEquals($out, clientIP(true)); - } - - function test_proxy2_local_single(){ - $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; - $_SERVER['HTTP_X_REAL_IP'] = ''; - $_SERVER['HTTP_X_FORWARDED_FOR'] = '77.77.77.77'; - $out = '77.77.77.77'; - $this->assertEquals($out, clientIP(true)); - } - - function test_proxyhops1_local_single(){ - $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; - $_SERVER['HTTP_X_REAL_IP'] = ''; - $_SERVER['HTTP_X_FORWARDED_FOR'] = '77.77.77.77,66.66.66.66'; - $out = '77.77.77.77'; - $this->assertEquals($out, clientIP(true)); - } - - function test_proxyhops2_local_single(){ - $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; - $_SERVER['HTTP_X_REAL_IP'] = ''; - $_SERVER['HTTP_X_FORWARDED_FOR'] = '10.0.0.1,66.66.66.66'; - $out = '66.66.66.66'; - $this->assertEquals($out, clientIP(true)); - } - - function test_local_all(){ - $_SERVER['REMOTE_ADDR'] = '123.123.123.123'; - $_SERVER['HTTP_X_REAL_IP'] = ''; - $_SERVER['HTTP_X_FORWARDED_FOR'] = '127.0.0.1'; - $out = '123.123.123.123,127.0.0.1'; - $this->assertEquals($out, clientIP()); - } - - function test_local1_single(){ - $_SERVER['REMOTE_ADDR'] = '123.123.123.123'; - $_SERVER['HTTP_X_REAL_IP'] = ''; - $_SERVER['HTTP_X_FORWARDED_FOR'] = '127.0.0.1'; - $out = '123.123.123.123'; - $this->assertEquals($out, clientIP(true)); - } - - function test_local2_single(){ - $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; - $_SERVER['HTTP_X_REAL_IP'] = ''; - $_SERVER['HTTP_X_FORWARDED_FOR'] = '123.123.123.123'; - $out = '123.123.123.123'; - $this->assertEquals($out, clientIP(true)); - } - - function test_local3_single(){ - $_SERVER['REMOTE_ADDR'] = '123.123.123.123'; - $_SERVER['HTTP_X_REAL_IP'] = ''; - $_SERVER['HTTP_X_FORWARDED_FOR'] = '127.0.0.1,10.0.0.1,192.168.0.2,172.17.1.1,172.21.1.1,172.31.1.1'; - $out = '123.123.123.123'; - $this->assertEquals($out, clientIP(true)); - } - - function test_local4_single(){ - $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; - $_SERVER['HTTP_X_REAL_IP'] = ''; - $_SERVER['HTTP_X_FORWARDED_FOR'] = '192.168.0.5'; - $out = '192.168.0.5'; - $this->assertEquals($out, clientIP(true)); - } - - function test_garbage_all(){ - $_SERVER['REMOTE_ADDR'] = '123.123.123.123'; - $_SERVER['HTTP_X_REAL_IP'] = ''; - $_SERVER['HTTP_X_FORWARDED_FOR'] = 'some garbage, or something, 222'; - $out = '123.123.123.123'; - $this->assertEquals($out, clientIP()); - } - - function test_garbage_single(){ - $_SERVER['REMOTE_ADDR'] = '123.123.123.123'; - $_SERVER['HTTP_X_REAL_IP'] = ''; - $_SERVER['HTTP_X_FORWARDED_FOR'] = 'some garbage, or something, 222'; - $out = '123.123.123.123'; - $this->assertEquals($out, clientIP(true)); - } - - function test_garbageonly_all(){ - $_SERVER['REMOTE_ADDR'] = 'argh'; - $_SERVER['HTTP_X_REAL_IP'] = ''; - $_SERVER['HTTP_X_FORWARDED_FOR'] = 'some garbage, or something, 222'; - $out = '0.0.0.0'; - $this->assertEquals($out, clientIP()); - } - - function test_garbageonly_single(){ - $_SERVER['REMOTE_ADDR'] = 'argh'; - $_SERVER['HTTP_X_REAL_IP'] = ''; - $_SERVER['HTTP_X_FORWARDED_FOR'] = 'some garbage, or something, 222'; - $out = '0.0.0.0'; - $this->assertEquals($out, clientIP(true)); - } - - function test_malicious(){ - $_SERVER['REMOTE_ADDR'] = ''; - $_SERVER['HTTP_X_REAL_IP'] = ''; - $_SERVER['HTTP_X_FORWARDED_FOR'] = '<?php set_time_limit(0);echo \'my_delim\';passthru(123.123.123.123);die;?>'; - $out = '0.0.0.0'; - $this->assertEquals($out, clientIP()); - } - - function test_malicious_with_remote_addr(){ - $_SERVER['REMOTE_ADDR'] = '8.8.8.8'; - $_SERVER['HTTP_X_REAL_IP'] = ''; - $_SERVER['HTTP_X_FORWARDED_FOR'] = '<?php set_time_limit(0);echo \'my_delim\';passthru(\',123.123.123.123,\');die;?>'; - $out = '8.8.8.8'; - $this->assertEquals($out, clientIP(true)); - } - - function test_proxied_malicious_with_remote_addr(){ - $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; - $_SERVER['HTTP_X_REAL_IP'] = ''; - $_SERVER['HTTP_X_FORWARDED_FOR'] = '8.8.8.8,<?php set_time_limit(0);echo \'my_delim\';passthru(\',123.123.123.123,\');die;?>'; - $out = '127.0.0.1,8.8.8.8,123.123.123.123'; - $this->assertEquals($out, clientIP()); - } + $addresses = [ + 'A' => '123.123.123.123', + 'B' => '22.22.22.22', + 'C' => '33.33.33.33', + 'D' => '192.168.11.1', + 'E' => '44.44.44.44', + ]; + + $_SERVER['REMOTE_ADDR'] = str_replace(array_keys($addresses), array_values($addresses), $remoteAddr); + $_SERVER['HTTP_X_REAL_IP'] = str_replace(array_keys($addresses), array_values($addresses), $realIp); + $_SERVER['HTTP_X_FORWARDED_FOR'] = str_replace(array_keys($addresses), array_values($addresses), $forwardedFor); + $conf['realip'] = $useRealIp; + + foreach ($this->configs as $config) { + $conf['trustedproxy'] = $config; + $this->assertEquals(str_replace(array_keys($addresses), array_values($addresses), $expected), clientIP($single)); + } + } + + /** + * Test clientIP() with IPv6 addresses. + * + * @dataProvider client_ip_all_provider + * + * @param string $remoteAddr The TCP/IP remote IP address. + * @param bool $useRealIp True if using the X-Real-IP header is enabled in the config. + * @param string $realIp The X-Real-IP header. + * @param string $forwardedFor The X-Forwarded-For header. + * @param bool $single True to return the most likely client IP, false to return all candidates. + * @param string $expected The expected function result. + * + * @return void + */ + public function test_client_ip_v6(string $remoteAddr, bool $useRealIp, string $realIp, string $forwardedFor, bool $single, string $expected) : void { + global $conf; - // IPv6 + $addresses = [ + 'A' => '1234:1234:1234:1234:1234:1234:1234:1234', + 'B' => '22:aa:22:bb:22:cc:22:dd', + 'C' => '33:aa:33:bb:33:cc:33:dd', + 'D' => '::1', + 'E' => '44:aa:44:bb:44:cc:44:dd', + ]; - function test_simple_single_ipv6(){ - $_SERVER['REMOTE_ADDR'] = '1234:1234:1234:1234:1234:1234:1234:1234'; - $_SERVER['HTTP_X_REAL_IP'] = ''; - $_SERVER['HTTP_X_FORWARDED_FOR'] = ''; - $out = '1234:1234:1234:1234:1234:1234:1234:1234'; - $this->assertEquals($out, clientIP(true)); - } + $_SERVER['REMOTE_ADDR'] = str_replace(array_keys($addresses), array_values($addresses), $remoteAddr); + $_SERVER['HTTP_X_REAL_IP'] = str_replace(array_keys($addresses), array_values($addresses), $realIp); + $_SERVER['HTTP_X_FORWARDED_FOR'] = str_replace(array_keys($addresses), array_values($addresses), $forwardedFor); + $conf['realip'] = $useRealIp; - function test_proxyhops_garbage_all_ipv4_and_ipv6(){ - $_SERVER['REMOTE_ADDR'] = '1234:1234:1234:1234:1234:1234:1234:1234'; - $_SERVER['HTTP_X_REAL_IP'] = '1.1.1.1'; - $_SERVER['HTTP_X_FORWARDED_FOR'] = '777:777:777:777:777:777:777:777,::1,skipme,66.66.66.66'; - $out = '1234:1234:1234:1234:1234:1234:1234:1234,777:777:777:777:777:777:777:777,::1,66.66.66.66,1.1.1.1'; - $this->assertEquals($out, clientIP()); + foreach ($this->configs as $config) { + $conf['trustedproxy'] = $config; + $this->assertEquals(str_replace(array_keys($addresses), array_values($addresses), $expected), clientIP($single)); + } } - } - -//Setup VIM: ex: et ts=4 : |