From 3f04f8bf7fd9d3b5ac4ea7d96c709f77ba5553f1 Mon Sep 17 00:00:00 2001 From: Bryce Kwon Date: Sat, 7 Nov 2026 14:36:42 -1000 Subject: Give the outsider account a hash of its own Every account shared one hash, so the binding of a session to its account's hash could not tell accounts apart, and an account_hash that handed back the wrong account's hash passed. --- tests/extensions/test-auth.lua | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tests/extensions/test-auth.lua b/tests/extensions/test-auth.lua index 111fbbb..295cb92 100644 --- a/tests/extensions/test-auth.lua +++ b/tests/extensions/test-auth.lua @@ -31,12 +31,15 @@ end -- other fails. local password = "open sesame" local stored_hash = real_hash or "$6$rounds=300000$testsalt$" .. password +-- carol never logs in, and her hash only has to differ from Alice's, so a +-- session bound to one account's hash cannot pass for another's. +local carol_hash = "$6$rounds=5000$carolsalt$carols-password" if variant == "file" then local users_file = io.open(directory .. "/auth-users", "w") users_file:write("Alice:" .. stored_hash .. "\r\n") users_file:write("not a parsable line\n") - users_file:write("carol:" .. stored_hash .. "\n") + users_file:write("carol:" .. carol_hash .. "\n") users_file:close() local groups_file = io.open(directory .. "/auth-groups", "w") groups_file:write("DEVS:Alice, bob\n") @@ -62,7 +65,7 @@ local inline_config = { "\t[\"empty-repo\"] = {},\n" }, { "local users = {\n", "local users = {\n" .. "\tAlice = \"" .. stored_hash .. "\",\n" .. - "\tcarol = \"" .. stored_hash .. "\",\n" }, + "\tcarol = \"" .. carol_hash .. "\",\n" }, } -- Every load keeps its signing secret in the run's directory, at the path @@ -181,7 +184,8 @@ local hash = account_hash("ALICE") h.equals("an account is found whatever its case", hash, stored_hash) h.equals("an unknown account is not", account_hash("nobody"), nil) local _, stand_in = account_hash("nobody") -h.equals("it brings another account's hash to spend instead", stand_in, stored_hash) +h.check("it brings another account's hash to spend instead", + stand_in == stored_hash or stand_in == carol_hash, tostring(stand_in)) local userset = repo_userset("secret-repo") h.check("a protected repository lists its users", @@ -431,7 +435,7 @@ if variant == "file" then h.redirect_file("/etc/cgit-auth/groups", directory .. "/auth-groups") end -local outsider = secure_value("username", "carol", now + 3600, stored_hash) +local outsider = secure_value("username", "carol", now + 3600, carol_hash) h.equals("a signed session for an outsider is turned away", visit("secret-repo", outsider), 0) h.equals("while one in the second group lets them in", visit("both-repo", outsider), 1) @@ -565,7 +569,8 @@ h.contains("a name cannot forge a log line of its own", h.error_log(), crypt_settings = {} 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.check("a missing account spends crypt on a configured hash", + crypt_settings[1] == stored_hash or crypt_settings[1] == carol_hash, tostring(crypt_settings[1])) 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") -- cgit 2.12.1