Skip to content

Commit

Permalink
feat: Add a header which signals that the request was throttled
Browse files Browse the repository at this point in the history
Signed-off-by: Joas Schilling <[email protected]>
  • Loading branch information
nickvergessen committed Aug 14, 2023
1 parent eedd4ff commit 5f5132f
Showing 1 changed file with 14 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
* @package OC\AppFramework\Middleware\Security
*/
class BruteForceMiddleware extends Middleware {
private int $delaySlept = 0;

public function __construct(
protected ControllerMethodReflector $reflector,
protected Throttler $throttler,
Expand All @@ -67,7 +69,7 @@ public function beforeController($controller, $methodName) {

if ($this->reflector->hasAnnotation('BruteForceProtection')) {
$action = $this->reflector->getAnnotationParameter('BruteForceProtection', 'action');
$this->throttler->sleepDelayOrThrowOnMax($this->request->getRemoteAddress(), $action);
$this->delaySlept += $this->throttler->sleepDelayOrThrowOnMax($this->request->getRemoteAddress(), $action);
} else {
$reflectionMethod = new ReflectionMethod($controller, $methodName);
$attributes = $reflectionMethod->getAttributes(BruteForceProtection::class);
Expand All @@ -79,7 +81,7 @@ public function beforeController($controller, $methodName) {
/** @var BruteForceProtection $protection */
$protection = $attribute->newInstance();
$action = $protection->getAction();
$this->throttler->sleepDelayOrThrowOnMax($remoteAddress, $action);
$this->delaySlept += $this->throttler->sleepDelayOrThrowOnMax($remoteAddress, $action);
}
}
}
Expand All @@ -95,7 +97,7 @@ public function afterController($controller, $methodName, Response $response) {
$action = $this->reflector->getAnnotationParameter('BruteForceProtection', 'action');
$ip = $this->request->getRemoteAddress();
$this->throttler->registerAttempt($action, $ip, $response->getThrottleMetadata());
$this->throttler->sleepDelayOrThrowOnMax($ip, $action);
$this->delaySlept += $this->throttler->sleepDelayOrThrowOnMax($ip, $action);
} else {
$reflectionMethod = new ReflectionMethod($controller, $methodName);
$attributes = $reflectionMethod->getAttributes(BruteForceProtection::class);
Expand All @@ -111,7 +113,7 @@ public function afterController($controller, $methodName, Response $response) {

if (!isset($metaData['action']) || $metaData['action'] === $action) {
$this->throttler->registerAttempt($action, $ip, $metaData);
$this->throttler->sleepDelayOrThrowOnMax($ip, $action);
$this->delaySlept += $this->throttler->sleepDelayOrThrowOnMax($ip, $action);
}
}
} else {
Expand All @@ -127,6 +129,14 @@ public function afterController($controller, $methodName, Response $response) {
}
}

if ($this->delaySlept) {
$headers = $response->getHeaders();
if (!isset($headers['X-Nextcloud-Bruteforce-Throttled'])) {
$headers['X-Nextcloud-Bruteforce-Throttled'] = $this->delaySlept . 'ms';
}
$response->setHeaders($headers);
}

return parent::afterController($controller, $methodName, $response);
}

Expand Down

0 comments on commit 5f5132f

Please sign in to comment.