aboutsummaryrefslogtreecommitdiff
path: root/internal/player/hardening_password_params_test.go
blob: 32b399b4b9990215e2b44438437dd41b0dce2a67 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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")
	}
}