Reset bruteforce attempt table on successful login

* only clear the entries that come from the same subnet, same action and same metadata

Signed-off-by: Morris Jobke <hey@morrisjobke.de>
This commit is contained in:
Morris Jobke 2017-11-23 13:37:50 +01:00
parent 2f3484ba88
commit 5a270c2715
No known key found for this signature in database
GPG Key ID: FE03C3A163FEDE68
2 changed files with 39 additions and 4 deletions

View File

@ -730,7 +730,7 @@ class OC {
OC_User::setIncognitoMode(true);
}
self::registerCacheHooks();
self::registerCleanupHooks();
self::registerFilesystemHooks();
self::registerShareHooks();
self::registerEncryptionWrapper();
@ -802,15 +802,23 @@ class OC {
}
/**
* register hooks for the cache
* register hooks for the cleanup of cache and bruteforce protection
*/
public static function registerCacheHooks() {
public static function registerCleanupHooks() {
//don't try to do this before we are properly setup
if (\OC::$server->getSystemConfig()->getValue('installed', false) && !self::checkUpgrade(false)) {
// NOTE: This will be replaced to use OCP
$userSession = self::$server->getUserSession();
$userSession->listen('\OC\User', 'postLogin', function () {
$userSession->listen('\OC\User', 'postLogin', function () use ($userSession) {
if (!defined('PHPUNIT_RUN')) {
// reset brute force delay for this IP address and username
$uid = \OC::$server->getUserSession()->getUser()->getUID();
$request = \OC::$server->getRequest();
$throttler = \OC::$server->getBruteForceThrottler();
$throttler->resetDelay($request->getRemoteAddress(), 'login', ['user' => $uid]);
}
try {
$cache = new \OC\Cache\File();
$cache->gc();

View File

@ -242,6 +242,33 @@ class Throttler {
return (int) \ceil($firstDelay * 1000);
}
/**
* Reset the throttling delay for an IP address, action and metadata
*
* @param string $ip
* @param string $action
* @param string $metadata
*/
public function resetDelay($ip, $action, $metadata) {
$ipAddress = new IpAddress($ip);
if ($this->isIPWhitelisted((string)$ipAddress)) {
return;
}
$cutoffTime = (new \DateTime())
->sub($this->getCutoff(43200))
->getTimestamp();
$qb = $this->db->getQueryBuilder();
$qb->delete('bruteforce_attempts')
->where($qb->expr()->gt('occurred', $qb->createNamedParameter($cutoffTime)))
->andWhere($qb->expr()->eq('subnet', $qb->createNamedParameter($ipAddress->getSubnet())))
->andWhere($qb->expr()->eq('action', $qb->createNamedParameter($action)))
->andWhere($qb->expr()->eq('metadata', $qb->createNamedParameter(json_encode($metadata))));
$qb->execute();
}
/**
* Will sleep for the defined amount of time
*