CVE-2023-34108: Insufficient Information (NVD-CWE-noinfo)
value: mailcow is a mail server suite based on Dovecot, Postfix and other open source software, that provides a modern web UI for user/server administration. A vulnerability has been discovered in mailcow which allows an attacker to manipulate internal Dovecot variables by using specially crafted passwords during the authentication process. The issue arises from the behavior of the `passwd-verify.lua` script, which is responsible for verifying user passwords during login attempts. Upon a successful login, the script returns a response in the format of "password=<valid-password>", indicating the successful authentication. By crafting a password with additional key-value pairs appended to it, an attacker can manipulate the returned string and influence the internal behavior of Dovecot. For example, using the password "123 mail_crypt_save_version=0" would cause the `passwd-verify.lua` script to return the string "password=123 mail_crypt_save_version=0". Consequently, Dovecot will interpret this string and set the internal variables accordingly, leading to unintended consequences. This vulnerability can be exploited by an authenticated attacker who has the ability to set their own password. Successful exploitation of this vulnerability could result in unauthorized access to user accounts, bypassing security controls, or other malicious activities. This issue has been patched in version `2023-05a`. Users are advised to upgrade. There are no known workarounds for this vulnerability.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
CVSS v3 base score: 8.8
Published: 2023-06-07T18:15Z
Repository: https://github.com/mailcow/mailcow-dockerized
Language: Shell
Files changed: data/Dockerfiles/dovecot/docker-entrypoint.sh
Commit date: 2023-05-30 09:09:41 +0200
Commit message: [Dovecot] remove pass return in Dovecot lua auth

Diff: diff --git a/data/Dockerfiles/dovecot/docker-entrypoint.sh b/data/Dockerfiles/dovecot/docker-entrypoint.sh
index 18746debc..05b552e9d 100755
--- a/data/Dockerfiles/dovecot/docker-entrypoint.sh
+++ b/data/Dockerfiles/dovecot/docker-entrypoint.sh
@@ -157,11 +157,11 @@ function auth_password_verify(req, pass)
     if req.password_verify(req, row.password, pass) == 1 then
       con:execute(string.format([[REPLACE INTO sasl_log (service, app_password, username, real_rip)
         VALUES ("%s", 0, "%s", "%s")]], con:escape(req.service), con:escape(req.user), con:escape(req.real_rip)))
       cur:close()
       con:close()
-      return dovecot.auth.PASSDB_RESULT_OK, "password=" .. pass
+      return dovecot.auth.PASSDB_RESULT_OK, "password=pass"
     end
     row = cur:fetch (row, "a")
   end
 
   -- check against app passwds for imap and smtp
@@ -178,17 +178,17 @@ function auth_password_verify(req, pass)
       if req.password_verify(req, row.password, pass) == 1 then
         -- if password is valid and protocol access is 1 OR real_rip matches SOGo, proceed
         if tostring(req.real_rip) == "__IPV4_SOGO__" then
           cur:close()
           con:close()
-          return dovecot.auth.PASSDB_RESULT_OK, "password=" .. pass
+          return dovecot.auth.PASSDB_RESULT_OK, "password=pass"
         elseif row.has_prot_access == "1" then
           con:execute(string.format([[REPLACE INTO sasl_log (service, app_password, username, real_rip)
             VALUES ("%s", %d, "%s", "%s")]], con:escape(req.service), row.id, con:escape(req.user), con:escape(req.real_rip)))
           cur:close()
           con:close()
-          return dovecot.auth.PASSDB_RESULT_OK, "password=" .. pass
+          return dovecot.auth.PASSDB_RESULT_OK, "password=pass"
         end
       end
       row = cur:fetch (row, "a")
     end
   end

Vulnerable code:       return dovecot.auth.PASSDB_RESULT_OK, "password=" .. pass
          return dovecot.auth.PASSDB_RESULT_OK, "password=" .. pass
          return dovecot.auth.PASSDB_RESULT_OK, "password=" .. pass
Fixed code:       return dovecot.auth.PASSDB_RESULT_OK, "password=pass"
          return dovecot.auth.PASSDB_RESULT_OK, "password=pass"
          return dovecot.auth.PASSDB_RESULT_OK, "password=pass"