CVE-2020-35847 (published 2020-12-30T01:15Z)

Agentejo Cockpit before 0.11.2 allows NoSQL injection via the Controller/Auth.php resetpassword function.

Severity: HIGH
CVSS v2 base score: 7.5 (AV:N/AC:L/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 9.8, CRITICAL (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-89
cwe_name: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
description: The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data.
extended_description: 
            
            
         
         

Fix information:
repo_url: https://github.com/agentejo/cockpit
commit_details: repo_url: https://github.com/agentejo/cockpit
author: Artur Heinze
author_date: 2020-09-25 23:18:28+02:00
msg: remove $fn, $func, $f as field filter ... add $where as an alternative (MongoLite)
repository: repo_url: https://github.com/agentejo/cockpit
repo_name: agentejo/cockpit
description: Add content management functionality to any site - plug & play / headless / api-first CMS
repo_language: JavaScript
owner: agentejo
file_changes: filename: Database.php
change_type: ModificationType.MODIFY
diff: @@ -235,6 +235,12 @@ class Database {
 
 class UtilArrayQuery {
 
+    protected static $closures = [];
+
+    public static function closureCall($uid, $doc) {
+        return call_user_func_array(self::$closures[$uid], [$doc]);
+    }
+
     public static function buildCondition($criteria, $concat = ' && ') {
 
         $fn = [];
@@ -268,11 +274,16 @@ class UtilArrayQuery {
 
                 case '$where':
 
-                    if (\is_callable($value)) {
-
-                        // need implementation
+                    if (\is_string($value) || !\is_callable($value)) {
+                        throw new \InvalidArgumentException($key.' Function should be callable');
                     }
 
+                    $uid = \uniqid('mongoliteCallable').bin2hex(random_bytes(5));
+
+                    self::$closures[$uid] = $value;
+
+                    $fn[] = '\\MongoLite\\UtilArrayQuery::closureCall("'.$uid.'", $document)';
+
                     break;
 
                 default:
@@ -426,14 +437,6 @@ class UtilArrayQuery {
                 $r = $a % $b[0] == $b[1] ?? 0;
                 break;
 
-            case '$func' :
-            case '$fn' :
-            case '$f' :
-                if (\is_string($b) || !\is_callable($b))
-                    throw new \InvalidArgumentException('Function should be callable');
-                $r = $b($a);
-                break;
-
             case '$exists':
                 $r = $b ? !\is_null($a) : \is_null($a);
                 break;

programming_language: PHP
repo_url: https://github.com/agentejo/cockpit
commit_details: repo_url: https://github.com/agentejo/cockpit
author: Artur Heinze
author_date: 2020-09-14 20:23:06+02:00
msg: don't allow callable strings for $func (MongoLite)
repository: repo_url: https://github.com/agentejo/cockpit
repo_name: agentejo/cockpit
description: Add content management functionality to any site - plug & play / headless / api-first CMS
repo_language: JavaScript
owner: agentejo
file_changes: filename: Database.php
change_type: ModificationType.MODIFY
diff: @@ -429,7 +429,7 @@ class UtilArrayQuery {
             case '$func' :
             case '$fn' :
             case '$f' :
-                if (! \is_callable($b))
+                if (\is_string($b) || !\is_callable($b))
                     throw new \InvalidArgumentException('Function should be callable');
                 $r = $b($a);
                 break;

programming_language: PHP
repo_url: https://github.com/agentejo/cockpit
commit_details: repo_url: https://github.com/agentejo/cockpit
author: Artur Heinze
author_date: 2020-09-14 14:20:51+02:00
msg: fix possible security issue for login
repository: repo_url: https://github.com/agentejo/cockpit
repo_name: agentejo/cockpit
description: Add content management functionality to any site - plug & play / headless / api-first CMS
repo_language: JavaScript
owner: agentejo
file_changes: filename: Auth.php
change_type: ModificationType.MODIFY
diff: @@ -17,6 +17,10 @@ class Auth extends \LimeExtra\Controller {
 
         if ($data = $this->param('auth')) {
 
+            if (!\is_string($data['user']) || !\is_string($data['password'])) {
+                return ['success' => false, 'error' => 'Pre-condition failed'];
+            }
+
             if (isset($data['user']) && $this->app->helper('utils')->isEmail($data['user'])) {
                 $data['email'] = $data['user'];
                 $data['user']  = '';
@@ -128,13 +132,21 @@ class Auth extends \LimeExtra\Controller {
 
         if ($token = $this->param('token')) {
 
+            if (!\is_string($token)) {
+                return false;
+            }
+
             $user = $this->app->storage->findOne('cockpit/accounts', ['_reset_token' => $token]);
 
             if (!$user) {
                 return false;
             }
 
-            $user['md5email'] = md5($user['email']);
+            $user = [
+                'md5email' => md5($user['email']),
+                'user' => $user['name'],
+                'name' => $user['user'],
+            ];
 
             return $this->render('cockpit:views/layouts/newpassword.php', compact('user', 'token'));
         }
@@ -147,6 +159,10 @@ class Auth extends \LimeExtra\Controller {
 
         if ($token = $this->param('token')) {
 
+            if (!\is_string($token)) {
+                return false;
+            }
+
             $user = $this->app->storage->findOne('cockpit/accounts', ['_reset_token' => $token]);
             $password = trim($this->param('password'));
 

programming_language: PHP