]> mop.ddnsfree.com - git repositories - brisk.git/commitdiff
stop sending the alarm password back on a failed admin check
authorMatteo Nastasi <nastasi@alternativeoutput.it>
Wed, 7 Oct 2026 07:23:08 +0000 (09:23 +0200)
committerMatteo Nastasi <nastasi@alternativeoutput.it>
Wed, 7 Oct 2026 07:23:08 +0000 (09:23 +0200)
When the userauth command of the control channel got a wrong hash, the
reply carried the hash received and the string it should have been made
from: G_alarm_passwd, the ip and the session of the admin, in clear, to
whoever had reached the channel. G_alarm_passwd is also the password of
admin.php and the key of the mail verification hashes.

The reply is now a bare "authentication failed". The failure goes to the
daemon log instead, with the name and the ip of the admin and without the
session, which is a credential too. The hashes are compared with
hash_equals rather than !=, which stops at the first differing byte.

Checked by calling direct_command() on a Sac_a_push built without its
constructor and a fake app: the right hash still answers 200, a wrong one
404 with nothing of the secret in the reply, where the previous code
returned it whole.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
web/Obj/sac-a-push.phh

index acf95a35af910605bd949162b3aef23796d54c6f..09d5fc1be693c91a9abd3d0c5542e7b427f5d6ee 100644 (file)
@@ -1473,8 +1473,17 @@ class Sac_a_push {
             if (($user->flags & USER_FLAG_TY_ADMIN) == 0x00)
                 return cmd_return(403, 'permission denied');
 
-            if (md5($G_alarm_passwd.$user->ip.$user->sess) != $cmd['private'])
-                return cmd_return(404, 'authentication failed ['.$cmd['private'].']['.$G_alarm_passwd.$user->ip.$user->sess.']');
+            /* The reply goes back to whoever reached the control channel:
+               it must not carry G_alarm_passwd, which is also the password
+               of admin.php and the key of the mail verification hashes.
+               The failure goes to the log instead, without the session,
+               which is a credential too. hash_equals: a != stops at the
+               first differing byte. */
+            if (!hash_equals(md5($G_alarm_passwd.$user->ip.$user->sess), (string)$cmd['private'])) {
+                fprintf(STDERR, "DIRECT: userauth failed for admin [%s] from [%s]\n",
+                        $user->name, $user->ip);
+                return cmd_return(404, 'authentication failed');
+            }
 
             return cmd_return(200, 'success');
         }