Diff options
| author | Bryce Kwon <bryce@brycekwon.com> | |
|---|---|---|
| committer | Bryce Kwon <bryce@brycekwon.com> | |
| commit | ||
| parent | ||
| tree | ||
| download | ||
Check every failed login answers and logs alike
Every post carried both fields, so the guards for a missing name or
password never ran. An unknown name was checked for the cookie and the
Location alone, so an extra header or body for it passed, and only the
wrong password case had its log line checked for the name and against
the password.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/extensions/test-auth.lua | 30 |
1 file changed, 27 insertions, 3 deletions
diff --git a/tests/extensions/test-auth.lua b/tests/extensions/test-auth.lua index dd719d9..d6982a4 100644 --- a/tests/extensions/test-auth.lua +++ b/tests/extensions/test-auth.lua @@ -544,6 +544,7 @@ constant_equals = real_constant_equals h.equals("and logs nothing", h.error_log(), "") out = login("Alice", "wrong", way_back) +local wrong_password = out h.contains("a bad password redirects the same way", out, "Status: 302") h.contains("back to the page with the failure flagged", out, "Location: /repo/?login=failed\n") h.contains("but clears the session cookie", out, "Set-Cookie: " .. session_name .. "=; ") @@ -557,10 +558,31 @@ h.contains("a name cannot forge a log line of its own", h.error_log(), -- A failed login for a name with no account spends crypt on a configured -- hash, the same work a real check costs, so timing tells nothing. crypt_settings = {} -out = login("nobody", "x", way_back) -h.contains("an unknown user is told nothing different", out, "Set-Cookie: " .. session_name .. "=; ") -h.contains("and lands on the same flagged page", out, "Location: /repo/?login=failed\n") +out = login("nobody", "unknown secret", way_back) +h.equals("an unknown user is told nothing different", out, wrong_password) h.equals("a missing account spends crypt on a configured hash", crypt_settings[1], stored_hash) +h.contains("and is logged by name", h.error_log(), "[cgit] Failed login as nobody for /repo/\n") +h.excludes("but never with the password", h.error_log(), "unknown secret") + +-- A post missing a field, or with a field that has no value, is a failed +-- login like any other rather than an error. +local back = url_encode(way_back) +for _, case in ipairs({ + { "with no name", "password=hunter2&redirect=" .. back, "" }, + { "with no password", "username=Alice&redirect=" .. back, "Alice" }, + { "with neither", "redirect=" .. back, "" }, + { "with a field that has no value", "hunter2&redirect=" .. back, "" }, +}) do + local answered, answer = pcall(run_action, "authenticate-post", { method = "POST", body = case[2] }) + h.check("a login " .. case[1] .. " is answered without an error", answered, tostring(answer)) + h.contains("a login " .. case[1] .. " clears the session cookie", tostring(answer), + "Set-Cookie: " .. session_name .. "=; ") + h.contains("a login " .. case[1] .. " lands on the flagged page", tostring(answer), + "Location: /repo/?login=failed\n") + h.contains("a login " .. case[1] .. " is logged", h.error_log(), + "[cgit] Failed login as " .. case[3] .. " for /repo/\n") + h.excludes("a login " .. case[1] .. " never logs a password", h.error_log(), "hunter2") +end if variant == "file" then h.redirect_file("/etc/cgit-auth/users", directory .. "/auth-users-missing") @@ -583,6 +605,8 @@ crypt_settings = {} out = login("Alice", string.rep("a", 257), way_back) h.contains("an overlong password is turned down", out, "Set-Cookie: " .. session_name .. "=; ") h.equals("without spending crypt on it", #crypt_settings, 0) +h.contains("and is logged like any failed login", h.error_log(), "[cgit] Failed login as Alice for /repo/\n") +h.excludes("without the password", h.error_log(), string.rep("a", 257)) login("Alice", string.rep("a", 256), way_back) h.equals("a password at the cap is still checked", #crypt_settings, 1) |
