package player // Regression: Argon2id parameters parsed from a stored hash must be bounded // before they reach argon2.IDKey. A hand-edited or corrupted account file // (e.g. argon2id:1:4294967295:...) must fail the check, not request a // multi-TiB allocation that kills the process. import "testing" func TestCheckPasswordRejectsOutOfRangeArgonParams(t *testing.T) { // Enormous memory cost (0xFFFFFFFF KiB) with an otherwise well-formed // hash: must be rejected before hashing. huge := "argon2id:1:4294967295:2:AAAAAAAAAAAAAAAAAAAAAA:0011223344556677889900112233445566778899001122334455667788990011" if CheckPassword("pw", huge) { t.Fatal("out-of-range Argon2 memory cost was accepted") } // Negative values would wrap through uint32 under a naive conversion. negative := "argon2id:-1:-1:-1:AAAAAAAAAAAAAAAAAAAAAA:0011223344556677889900112233445566778899001122334455667788990011" if CheckPassword("pw", negative) { t.Fatal("negative Argon2 parameters were accepted") } // Absurd time cost is bounded too. slow := "argon2id:4294967295:65536:2:AAAAAAAAAAAAAAAAAAAAAA:0011223344556677889900112233445566778899001122334455667788990011" if CheckPassword("pw", slow) { t.Fatal("out-of-range Argon2 time cost was accepted") } } func TestCheckPasswordAcceptsNormalHashes(t *testing.T) { hashed, err := HashPassword("s3cret") if err != nil { t.Fatal(err) } if !CheckPassword("s3cret", hashed) { t.Fatal("valid Argon2id hash rejected") } if CheckPassword("wrong", hashed) { t.Fatal("wrong password accepted") } }