CVE-2020-8891 (published 2020-02-12T00:15Z)

An issue was discovered in MISP before 2.4.121. It did not canonicalize usernames when trying to block a brute-force series of invalid requests.

Severity: MEDIUM
CVSS v2 base score: 4.3 (AV:N/AC:M/Au:N/C:N/I:P/A:N)
CVSS v3 base score: 5.9, MEDIUM (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N)

Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/MISP/MISP
commit_details: repo_url: https://github.com/MISP/MISP
author: iglocska
author_date: 2020-02-10 11:41:54+01:00
msg: fix: [security] Further fixes to the bruteforce handling

- resolved a potential failure of the subsystem when the MySQL and the webserver time settings are diverged
  - as reported by Dawid Czarnecki
- several tightenings of the checks to avoid potential foul play
repository: repo_url: https://github.com/MISP/MISP
repo_name: MISP/MISP
description: MISP (core software) - Open Source Threat Intelligence and Sharing Platform
repo_language: PHP
owner: MISP
file_changes: filename: UsersController.php
change_type: ModificationType.MODIFY
diff: @@ -1066,6 +1066,7 @@ class UsersController extends AppController
             $this->Bruteforce = ClassRegistry::init('Bruteforce');
             if (!empty($this->request->data['User']['email'])) {
                 if ($this->Bruteforce->isBlacklisted($_SERVER['REMOTE_ADDR'], $this->request->data['User']['email'])) {
+                    $expire = Configure::check('SecureAuth.expire') ? Configure::read('SecureAuth.expire') : 300;
                     throw new ForbiddenException('You have reached the maximum number of login attempts. Please wait ' . Configure::read('SecureAuth.expire') . ' seconds and try again.');
                 }
             }
@@ -1116,7 +1117,7 @@ class UsersController extends AppController
                 $this->Session->delete('Message.auth');
             }
             // don't display "invalid user" before first login attempt
-            if ($this->request->is('post')) {
+            if ($this->request->is('post') || $this->request->is('put')) {
                 $this->Flash->error(__('Invalid username or password, try again'));
                 if (isset($this->request->data['User']['email'])) {
                     $this->Bruteforce->insert($_SERVER['REMOTE_ADDR'], $this->request->data['User']['email']);

programming_language: PHP
filename: Bruteforce.php
change_type: ModificationType.MODIFY
diff: @@ -9,17 +9,19 @@ class Bruteforce extends AppModel
     {
         $this->Log = ClassRegistry::init('Log');
         $this->Log->create();
-        $expire = time() + Configure::read('SecureAuth.expire');
+        $expire = Configure::check('SecureAuth.expire') ? Configure::read('SecureAuth.expire') : 300;
+        $amount = Configure::check('SecureAuth.amount') ? Configure::read('SecureAuth.amount') : 5;
+        $expire = time() + $expire;
         $expire = date('Y-m-d H:i:s', $expire);
         $bruteforceEntry = array(
             'ip' => $ip,
-            'username' => $username,
+            'username' => trim(strtolower($username)),
             'expire' => $expire
         );
         $this->save($bruteforceEntry);
         $title = 'Failed login attempt using username ' . $username . ' from IP: ' . $_SERVER['REMOTE_ADDR'] . '.';
         if ($this->isBlacklisted($ip, $username)) {
-            $title .= 'This has tripped the bruteforce protection after  ' . Configure::read('SecureAuth.amount') . ' failed attempts. The user is now blacklisted for ' . Configure::read('SecureAuth.expire') . ' seconds.';
+            $title .= 'This has tripped the bruteforce protection after  ' . $amount . ' failed attempts. The user is now blacklisted for ' . $expire . ' seconds.';
         }
         $log = array(
                 'org' => 'SYSTEM',
@@ -36,10 +38,11 @@ class Bruteforce extends AppModel
     {
         $dataSourceConfig = ConnectionManager::getDataSource('default')->config;
         $dataSource = $dataSourceConfig['datasource'];
+        $expire = date('Y-m-d H:i:s', time());
         if ($dataSource == 'Database/Mysql') {
-            $sql = 'DELETE FROM bruteforces WHERE `expire` <= NOW();';
+            $sql = 'DELETE FROM bruteforces WHERE `expire` <= "' . $expire . '";';
         } elseif ($dataSource == 'Database/Postgres') {
-            $sql = 'DELETE FROM bruteforces WHERE expire <= NOW();';
+            $sql = 'DELETE FROM bruteforces WHERE expire <= "' . $expire . '";';
         }
         $this->query($sql);
     }

programming_language: PHP
repo_url: https://github.com/MISP/MISP
commit_details: repo_url: https://github.com/MISP/MISP
author: iglocska
author_date: 2020-02-08 09:35:37+01:00
msg: fix: [security] brutefoce protection rules tightened

- as reported by Dawid Czarnecki
repository: repo_url: https://github.com/MISP/MISP
repo_name: MISP/MISP
description: MISP (core software) - Open Source Threat Intelligence and Sharing Platform
repo_language: PHP
owner: MISP
file_changes: filename: Bruteforce.php
change_type: ModificationType.MODIFY
diff: @@ -49,11 +49,14 @@ class Bruteforce extends AppModel
         // first remove old expired rows
         $this->clean();
         // count
-        $params = array('conditions' => array(
-                        'Bruteforce.ip' => $ip,
-                        'Bruteforce.username' => $username),);
+        $params = array(
+            'conditions' => array(
+            'Bruteforce.ip' => $ip,
+            'LOWER(Bruteforce.username)' => trim(strtolower($username)))
+        );
         $count = $this->find('count', $params);
-        if ($count >= Configure::read('SecureAuth.amount')) {
+        $amount = Configure::check('SecureAuth.amount') ? Configure::read('SecureAuth.amount') : 5;
+        if ($count >= $amount) {
             return true;
         } else {
             return false;

programming_language: PHP