Vulnerability: GLPI is a Free Asset and IT Management Software package, Data center management, ITIL Service Desk, licenses tracking and software auditing. In affected versions there is a SQL injection vulnerability which is possible on login page. No user credentials are required to exploit this vulnerability. Users are advised to upgrade as soon as possible. There are no known workarounds for this issue.
Vulnerability ID: CVE-2022-31061
CWE: CWE-89
Severity score: 6.4
Project: https://github.com/glpi-project/glpi
Published: 2022-06-28
File: src/Auth.php
Commit message: Merge pull request from GHSA-w2gc-v2gm-q7wq
Commit author: Johan Cwiklinski

Vulnerable version (before fix):
 public function login($login_name, $login_password, $noauto = false, $remember_m         if ($login_auth == 'local') {             $authtype = self::DB_GLPI;             $this->user->fields["authtype"] = self::DB_GLPI;         } else if (strstr($login_auth, '-')) {             $auths = explode('-', $login_auth);             $this->user->fields["auths_id"] = $auths[1];             if ($auths[0] == 'ldap') {                 $authtype = self::LDAP;                 $this->user->fields["authtype"] = self::LDAP;             } else if ($auths[0] == 'mail') {                 $authtype = self::MAIL;                 $this->user->fields["authtype"] = self::MAIL;             } else if ($auths[0] == 'external') {                 $authtype = self::EXTERNAL;                 $this->user->fields["authtype"] = self::EXTERNAL;             }         }         if (!$noauto && ($authtype = self::checkAlternateAuthSystems())) {             if (

Fixed version (after fix):
 public function login($login_name, $login_password, $noauto = false, $remember_m         if ($login_auth == 'local') {             $authtype = self::DB_GLPI;             $this->user->fields["authtype"] = self::DB_GLPI;         } else if (preg_match('/^(?<type>ldap|mail|external)-(?<id>\d+)$/', $login_auth, $auth_matches)) {             $this->user->fields["auths_id"] = (int)$auth_matches['id'];             if ($auth_matches['type'] == 'ldap') {                 $authtype = self::LDAP;             } else if ($auth_matches['type'] == 'mail') {                 $authtype = self::MAIL;             } else if ($auth_matches['type'] == 'external') {                 $authtype = self::EXTERNAL;             }             $this->user->fields['authtype'] = $authtype;         }         if (!$noauto && ($authtype = self::checkAlternateAuthSystems())) {             if (

Patch:
patch: @@ -736,19 +736,16 @@ public function login($login_name, $login_password, $noauto = false, $remember_m
         if ($login_auth == 'local') {
             $authtype = self::DB_GLPI;
             $this->user->fields["authtype"] = self::DB_GLPI;
-        } else if (strstr($login_auth, '-')) {
-            $auths = explode('-', $login_auth);
-            $this->user->fields["auths_id"] = $auths[1];
-            if ($auths[0] == 'ldap') {
+        } else if (preg_match('/^(?<type>ldap|mail|external)-(?<id>\d+)$/', $login_auth, $auth_matches)) {
+            $this->user->fields["auths_id"] = (int)$auth_matches['id'];
+            if ($auth_matches['type'] == 'ldap') {
                 $authtype = self::LDAP;
-                $this->user->fields["authtype"] = self::LDAP;
-            } else if ($auths[0] == 'mail') {
+            } else if ($auth_matches['type'] == 'mail') {
                 $authtype = self::MAIL;
-                $this->user->fields["authtype"] = self::MAIL;
-            } else if ($auths[0] == 'external') {
+            } else if ($auth_matches['type'] == 'external') {
                 $authtype = self::EXTERNAL;
-                $this->user->fields["authtype"] = self::EXTERNAL;
             }
+            $this->user->fields['authtype'] = $authtype;
         }
         if (!$noauto && ($authtype = self::checkAlternateAuthSystems())) {
             if (
path: src/Auth.php