diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 7848ac4b195ac..6eea8812edd8a 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -8619,8 +8619,22 @@ function getremoteaddr($default='0.0.0.0') { } if (!($variablestoskip & GETREMOTEADDR_SKIP_HTTP_X_FORWARDED_FOR)) { if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { - $hdr = explode(",", $_SERVER['HTTP_X_FORWARDED_FOR']); - $address = cleanremoteaddr($hdr[0]); + $forwardedaddresses = explode(",", $_SERVER['HTTP_X_FORWARDED_FOR']); + $address = $forwardedaddresses[0]; + + if (substr_count($address, ":") > 1) { + // Remove port and brackets from IPv6. + if (preg_match("/\[(.*)\]:/", $address, $matches)) { + $address = $matches[1]; + } + } else { + // Remove port from IPv4. + if (substr_count($address, ":") == 1) { + $address = explode(":", $address)[0]; + } + } + + $address = cleanremoteaddr($address); return $address ? $address : $default; } } diff --git a/lib/tests/moodlelib_test.php b/lib/tests/moodlelib_test.php index e5331234308ef..fe1d6d601137b 100644 --- a/lib/tests/moodlelib_test.php +++ b/lib/tests/moodlelib_test.php @@ -2780,4 +2780,49 @@ public function test_count_words() { $count = count_words('one…two ブルース … カンベッル'); $this->assertEquals(4, $count); } + /** + * Tests the getremoteaddr() function. + */ + public function test_getremoteaddr() { + $xforwardedfor = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : null; + + $_SERVER['HTTP_X_FORWARDED_FOR'] = ''; + $noip = getremoteaddr('1.1.1.1'); + $this->assertEquals('1.1.1.1', $noip); + + $_SERVER['HTTP_X_FORWARDED_FOR'] = ''; + $noip = getremoteaddr(); + $this->assertEquals('0.0.0.0', $noip); + + $_SERVER['HTTP_X_FORWARDED_FOR'] = '127.0.0.1'; + $singleip = getremoteaddr(); + $this->assertEquals('127.0.0.1', $singleip); + + $_SERVER['HTTP_X_FORWARDED_FOR'] = '127.0.0.1,127.0.0.2'; + $twoip = getremoteaddr(); + $this->assertEquals('127.0.0.1', $twoip); + + $_SERVER['HTTP_X_FORWARDED_FOR'] = '127.0.0.1,127.0.0.2, 127.0.0.3'; + $threeip = getremoteaddr(); + $this->assertEquals('127.0.0.1', $threeip); + + $_SERVER['HTTP_X_FORWARDED_FOR'] = '127.0.0.1:65535,127.0.0.2'; + $portip = getremoteaddr(); + $this->assertEquals('127.0.0.1', $portip); + + $_SERVER['HTTP_X_FORWARDED_FOR'] = '0:0:0:0:0:0:0:1,127.0.0.2'; + $portip = getremoteaddr(); + $this->assertEquals('0:0:0:0:0:0:0:1', $portip); + + $_SERVER['HTTP_X_FORWARDED_FOR'] = '0::1,127.0.0.2'; + $portip = getremoteaddr(); + $this->assertEquals('0:0:0:0:0:0:0:1', $portip); + + $_SERVER['HTTP_X_FORWARDED_FOR'] = '[0:0:0:0:0:0:0:1]:65535,127.0.0.2'; + $portip = getremoteaddr(); + $this->assertEquals('0:0:0:0:0:0:0:1', $portip); + + $_SERVER['HTTP_X_FORWARDED_FOR'] = $xforwardedfor; + + } }