Skip to content

Commit

Permalink
Reset bruteforce attempt table on successful login
Browse files Browse the repository at this point in the history
* only clear the entries that come from the same subnet, same action and same metadata

Signed-off-by: Morris Jobke <hey@morrisjobke.de>
  • Loading branch information
MorrisJobke committed Nov 23, 2017
1 parent 2f3484b commit 0d6a08e
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 4 deletions.
14 changes: 10 additions & 4 deletions lib/base.php
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,7 @@ public static function init() {
OC_User::setIncognitoMode(true);
}

self::registerCacheHooks();
self::registerCleanupHooks();
self::registerFilesystemHooks();
self::registerShareHooks();
self::registerEncryptionWrapper();
Expand Down Expand Up @@ -802,15 +802,21 @@ public static function init() {
}

/**
* 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) {
// 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();
Expand Down
27 changes: 27 additions & 0 deletions lib/private/Security/Bruteforce/Throttler.php
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,33 @@ public function getDelay($ip, $action = '') {
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
*
Expand Down

0 comments on commit 0d6a08e

Please sign in to comment.