aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/_test/tests/inc/common_clientip.test.php
diff options
context:
space:
mode:
Diffstat (limited to '_test/tests/inc/common_clientip.test.php')
-rw-r--r--_test/tests/inc/common_clientip.test.php356
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 :