Add trusted IPs in config and try to ban forwarded IP on failed login
* Add a new settings (which needs to be manually set): `security.trusted_proxies` * On login failure, if the `REMOTE_ADDR` is in the trusted proxies, try to retrieve the forwarded IP in headers. * If found, the client address is added in ipbans, else we do nothing. Fixes #409
This commit is contained in:
parent
c7a42ab1d9
commit
50d1791838
3 changed files with 94 additions and 1 deletions
|
@ -215,3 +215,29 @@ function page_url($server)
|
|||
}
|
||||
return index_url($server);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the initial IP forwarded by the reverse proxy.
|
||||
*
|
||||
* Inspired from: https://github.com/zendframework/zend-http/blob/master/src/PhpEnvironment/RemoteAddress.php
|
||||
*
|
||||
* @param array $server $_SERVER array which contains HTTP headers.
|
||||
* @param array $trustedIps List of trusted IP from the configuration.
|
||||
*
|
||||
* @return string|bool The forwarded IP, or false if none could be extracted.
|
||||
*/
|
||||
function getIpAddressFromProxy($server, $trustedIps)
|
||||
{
|
||||
$forwardedIpHeader = 'HTTP_X_FORWARDED_FOR';
|
||||
if (empty($server[$forwardedIpHeader])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$ips = preg_split('/\s*,\s*/', $server[$forwardedIpHeader]);
|
||||
$ips = array_diff($ips, $trustedIps);
|
||||
if (empty($ips)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return array_pop($ips);
|
||||
}
|
||||
|
|
11
index.php
11
index.php
|
@ -318,8 +318,17 @@ include $conf->get('resource.ban_file', 'data/ipbans.php');
|
|||
function ban_loginFailed($conf)
|
||||
{
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
$trusted = $conf->get('security.trusted_proxies', array());
|
||||
if (in_array($ip, $trusted)) {
|
||||
$ip = getIpAddressFromProxy($_SERVER, $trusted);
|
||||
if (!$ip) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
$gb = $GLOBALS['IPBANS'];
|
||||
if (!isset($gb['FAILURES'][$ip])) $gb['FAILURES'][$ip]=0;
|
||||
if (! isset($gb['FAILURES'][$ip])) {
|
||||
$gb['FAILURES'][$ip]=0;
|
||||
}
|
||||
$gb['FAILURES'][$ip]++;
|
||||
if ($gb['FAILURES'][$ip] > ($conf->get('security.ban_after') - 1))
|
||||
{
|
||||
|
|
58
tests/HttpUtils/GetIpAdressFromProxyTest.php
Normal file
58
tests/HttpUtils/GetIpAdressFromProxyTest.php
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
require_once 'application/HttpUtils.php';
|
||||
|
||||
/**
|
||||
* Unitary tests for getIpAddressFromProxy()
|
||||
*/
|
||||
class GetIpAdressFromProxyTest extends PHPUnit_Framework_TestCase {
|
||||
|
||||
/**
|
||||
* Test without proxy
|
||||
*/
|
||||
public function testWithoutProxy()
|
||||
{
|
||||
$this->assertFalse(getIpAddressFromProxy(array(), array()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with a single IP in proxy header.
|
||||
*/
|
||||
public function testWithOneForwardedIp()
|
||||
{
|
||||
$ip = '1.1.1.1';
|
||||
$server = array('HTTP_X_FORWARDED_FOR' => $ip);
|
||||
$this->assertEquals($ip, getIpAddressFromProxy($server, array()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with a multiple IPs in proxy header.
|
||||
*/
|
||||
public function testWithMultipleForwardedIp()
|
||||
{
|
||||
$ip = '1.1.1.1';
|
||||
$ip2 = '2.2.2.2';
|
||||
|
||||
$server = array('HTTP_X_FORWARDED_FOR' => $ip .','. $ip2);
|
||||
$this->assertEquals($ip2, getIpAddressFromProxy($server, array()));
|
||||
|
||||
$server = array('HTTP_X_FORWARDED_FOR' => $ip .' , '. $ip2);
|
||||
$this->assertEquals($ip2, getIpAddressFromProxy($server, array()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with a trusted IP address.
|
||||
*/
|
||||
public function testWithTrustedIp()
|
||||
{
|
||||
$ip = '1.1.1.1';
|
||||
$ip2 = '2.2.2.2';
|
||||
|
||||
$server = array('HTTP_X_FORWARDED_FOR' => $ip);
|
||||
$this->assertFalse(getIpAddressFromProxy($server, array($ip)));
|
||||
|
||||
$server = array('HTTP_X_FORWARDED_FOR' => $ip .','. $ip2);
|
||||
$this->assertEquals($ip2, getIpAddressFromProxy($server, array($ip)));
|
||||
$this->assertFalse(getIpAddressFromProxy($server, array($ip, $ip2)));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue