xref: /dokuwiki/_test/tests/inc/common_clientip.test.php (revision a75803218144699ad4af53f4d8b1a890b705a22c)
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