route : ratelimit the errors to not allow the hackers to brute force the backend
git-svn-id: https://svn.fournier38.fr/svn/ProgSVN/trunk@2543 bf3deb0d-5f1a-0410-827f-c0cc1f45334c
This commit is contained in:
@@ -320,4 +320,22 @@ class test_route extends PHPUnit_Framework_TestCase
|
|||||||
echo $route->requestURL ();
|
echo $route->requestURL ();
|
||||||
$this->expectOutputString("var=1");
|
$this->expectOutputString("var=1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Ratelimiting in errors */
|
||||||
|
public function test_errorRateLimit1 ()
|
||||||
|
{
|
||||||
|
$route = new route ();
|
||||||
|
$route->error (new \Exception ("test1", 500));
|
||||||
|
$route->error (new \Exception ("test2", 500));
|
||||||
|
$route->error (new \Exception ("test3", 500));
|
||||||
|
$route->error (new \Exception ("test4", 500));
|
||||||
|
$route->error (new \Exception ("test5", 500));
|
||||||
|
$route->error (new \Exception ("test6", 500));
|
||||||
|
$route->error (new \Exception ("test7", 500));
|
||||||
|
$route->error (new \Exception ("test8", 500));
|
||||||
|
$route->error (new \Exception ("test9", 500));
|
||||||
|
$route->error (new \Exception ("test0", 500));
|
||||||
|
$route->error (new \Exception ("test11", 500));
|
||||||
|
$this->expectOutputRegex("#Too much error requests#");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
32
route.php
32
route.php
@@ -4,6 +4,7 @@
|
|||||||
@author Dominique Fournier <dominique@fournier38.fr> */
|
@author Dominique Fournier <dominique@fournier38.fr> */
|
||||||
|
|
||||||
require_once ("domframework/http.php");
|
require_once ("domframework/http.php");
|
||||||
|
require_once ("domframework/ratelimitfile.php");
|
||||||
|
|
||||||
/** The routing module, base of the DomFramework */
|
/** The routing module, base of the DomFramework */
|
||||||
class route
|
class route
|
||||||
@@ -32,6 +33,9 @@ class route
|
|||||||
just display a "Unauthorized" message */
|
just display a "Unauthorized" message */
|
||||||
public $authenticationURL = null;
|
public $authenticationURL = null;
|
||||||
|
|
||||||
|
// Ratelimit the errors in route.php to not allow the hackers to brute force
|
||||||
|
// the backend. The objct can be put to null to disable the feature
|
||||||
|
public $ratelimiter = null;
|
||||||
|
|
||||||
/// RENDERER PART ///
|
/// RENDERER PART ///
|
||||||
/** Output type to no previous catched renderer (allow : json, xml, txt html)
|
/** Output type to no previous catched renderer (allow : json, xml, txt html)
|
||||||
@@ -50,6 +54,12 @@ class route
|
|||||||
/** Array to variable definition */
|
/** Array to variable definition */
|
||||||
public $variable = array ();
|
public $variable = array ();
|
||||||
|
|
||||||
|
/** The route constructor : initialize the parameters */
|
||||||
|
function __construct ()
|
||||||
|
{
|
||||||
|
$this->ratelimiter = new ratelimitfile ();
|
||||||
|
}
|
||||||
|
|
||||||
/** Return the baseURL of the site
|
/** Return the baseURL of the site
|
||||||
Always finish with a slash
|
Always finish with a slash
|
||||||
@param string|null $module The module name (if thereis one) */
|
@param string|null $module The module name (if thereis one) */
|
||||||
@@ -485,6 +495,21 @@ class route
|
|||||||
/** Print an error page. If a custom page exists, use it
|
/** Print an error page. If a custom page exists, use it
|
||||||
@param $e Exception to print */
|
@param $e Exception to print */
|
||||||
public function error ($e)
|
public function error ($e)
|
||||||
|
{
|
||||||
|
$ipClient = null;
|
||||||
|
if (isset ($_SERVER["HTTP_X_FORWARDED_FOR"]))
|
||||||
|
$ipClient = $_SERVER["HTTP_X_FORWARDED_FOR"];
|
||||||
|
elseif (isset ($_SERVER["REMOTE_ADDR"]))
|
||||||
|
$ipClient = $_SERVER["REMOTE_ADDR"];
|
||||||
|
elseif (defined ("PHPUNIT"))
|
||||||
|
$ipClient = "CLI";
|
||||||
|
if ($this->ratelimiter !== null && $ipClient !== null &&
|
||||||
|
$this->ratelimiter->set ("error-$ipClient") === false)
|
||||||
|
{
|
||||||
|
$getCode = 406;
|
||||||
|
$message = dgettext("domframework", "Too much error requests");
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if ($e->getCode () === "" || $e->getCode () === 0)
|
if ($e->getCode () === "" || $e->getCode () === 0)
|
||||||
$getCode = 500;
|
$getCode = 500;
|
||||||
@@ -494,6 +519,7 @@ class route
|
|||||||
$message = $e->getMessage ();
|
$message = $e->getMessage ();
|
||||||
if ($e->getCode () === 0)
|
if ($e->getCode () === 0)
|
||||||
$message .= "<p>The Exception code was 0 and converted to 500</p>\n";
|
$message .= "<p>The Exception code was 0 and converted to 500</p>\n";
|
||||||
|
}
|
||||||
|
|
||||||
// If an error class/method is defined, use it in place of the default
|
// If an error class/method is defined, use it in place of the default
|
||||||
// one.
|
// one.
|
||||||
@@ -508,7 +534,7 @@ class route
|
|||||||
$a = new $this->errors[0];
|
$a = new $this->errors[0];
|
||||||
$method = $this->errors[1];
|
$method = $this->errors[1];
|
||||||
$a->$method ($getCode, $message);
|
$a->$method ($getCode, $message);
|
||||||
exit;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->authenticationURL !== null && $getCode === 401)
|
if ($this->authenticationURL !== null && $getCode === 401)
|
||||||
@@ -543,11 +569,11 @@ class route
|
|||||||
"{baseurlmodule}"=>$this->baseURLmodule()));
|
"{baseurlmodule}"=>$this->baseURLmodule()));
|
||||||
$renderer->variable = $this->variable;
|
$renderer->variable = $this->variable;
|
||||||
$renderer->run ();
|
$renderer->run ();
|
||||||
exit;
|
return true;
|
||||||
$class = "output".$this->output;
|
$class = "output".$this->output;
|
||||||
require_once ("$class.php");
|
require_once ("$class.php");
|
||||||
$output = new $class ();
|
$output = new $class ();
|
||||||
$output->out ($message, $http->codetext ($getCode));
|
$output->out ($message, $http->codetext ($getCode));
|
||||||
exit;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user