Commit dea0b6d
authored
fix(security): known-hosts Put fails closed on concurrent first-use key conflict (#668)
* fix(security): known-hosts Put fails closed on concurrent first-use key conflict
internal/knownhosts.Store.Put discarded the command tag, so a conflicting-key
INSERT that updated 0 rows returned nil. On a concurrent first-use race (two
first-ever dials to the same hostname — scheduler + manual scan, or scan +
liveness), the first connection records key A; a second arriving with a
DIFFERENT key B (an attacker's MITM key on one path) hits ON CONFLICT, the
`WHERE public_key = EXCLUDED.public_key` predicate is false, 0 rows update, and
Put returned nil — so the TOFU callback accepted the unverified key B and
presented the real credential to the attacker. Steady state was already safe
(later dials Get-hit A and reject B); the gap was strictly the concurrent
first-use window.
Fix: check tag.RowsAffected(); 0 rows means a different key is already stored, so
return ssh.ErrHostKeyMismatch and let the dial fail closed. Same key still
refreshes last_seen (1 row) and stays idempotent.
Regression test: Put A, then Put B for the same host returns ErrHostKeyMismatch
and leaves A stored. Found by the rc.13 security review.
* docs: use standard 'Fixed' category for the Unreleased docs entry
The docs-accuracy entry (#667) used a '### Docs' heading under [Unreleased],
which TestChangelog_UnreleasedCategoriesAreStandard rejects (only Added/Changed/
Deprecated/Removed/Fixed/Security are allowed there). Renamed to '### Fixed'.
Released sections may keep their '### Docs' heading; the test only gates
[Unreleased].1 parent 51dad74 commit dea0b6d
3 files changed
Lines changed: 50 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | | - | |
| 13 | + | |
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
| 17 | + | |
| 18 | + | |
17 | 19 | | |
18 | 20 | | |
19 | 21 | | |
| |||
47 | 49 | | |
48 | 50 | | |
49 | 51 | | |
50 | | - | |
| 52 | + | |
51 | 53 | | |
52 | 54 | | |
53 | 55 | | |
54 | 56 | | |
55 | 57 | | |
56 | | - | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
57 | 73 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
8 | 9 | | |
9 | 10 | | |
10 | 11 | | |
| 12 | + | |
11 | 13 | | |
12 | 14 | | |
13 | 15 | | |
| |||
49 | 51 | | |
50 | 52 | | |
51 | 53 | | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
0 commit comments