login

<     >

2023-07-24 16:21:43 (UTC-03:00)

Marcel Rodrigues <marcelgmr@gmail.com>

hash the password even if username is invalid

otherwise existing usernames can be leaked via timing

diff --git a/skopos.lua b/skopos.lua
index 4979514..cfc55c4 100644
--- a/skopos.lua
+++ b/skopos.lua
@@ -85,20 +85,24 @@ function App:routes()
         local nick = req.form.username
         local pass = req.form.password
         local user = self.model:get_user(nick)
+        local salt, hash
         if user == nil then
+            -- hash something as if we're trying to login anyway
+            salt = auth.get_salt()
+            hash = auth.hash_pass(pass, salt)
             self:log(LOG_WARN, "invalid username: "..nick)
-            return "/login", 303
-        end
-        local salt = auth.b64_dec(user.salt)
-        local hash = auth.hash_pass(pass, salt)
-        if hash == auth.b64_dec(user.hash) then
-            local session_id = auth.b64_enc(auth.uuid4())
-            self.sessions[session_id] = nick
-            self:log(LOG_INFO, "logged in as "..nick)
-            local cookie = {key="sid", val=session_id, path="/", age=3*24*60*60}
-            return "/", 303, "See Other", {cookie}
         else
-            self:log(LOG_WARN, "invalid password for "..nick)
+            salt = auth.b64_dec(user.salt)
+            hash = auth.hash_pass(pass, salt)
+            if hash == auth.b64_dec(user.hash) then
+                local session_id = auth.b64_enc(auth.uuid4())
+                self.sessions[session_id] = nick
+                self:log(LOG_INFO, "logged in as "..nick)
+                local cookie = {key="sid", val=session_id, path="/", age=3*24*60*60}
+                return "/", 303, "See Other", {cookie}
+            else
+                self:log(LOG_WARN, "invalid password for "..nick)
+            end
         end
         return "/login", 303
     end},