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