aboutsummaryrefslogtreecommitdiff
path: root/ssh/server.go
diff options
context:
space:
mode:
authorRoland Shoemaker <roland@golang.org>2024-12-03 09:03:03 -0800
committerGopher Robot <gobot@golang.org>2024-12-11 09:50:49 -0800
commitb4f1988a35dee11ec3e05d6bf3e90b695fbd8909 (patch)
tree69f31d6f5e0e04427c355f89a56ec2fde17814ad /ssh/server.go
parent7042ebcbe097f305ba3a93f9a22b4befa4b83d29 (diff)
downloadgo-x-crypto-0.31.0.tar.xz
ssh: make the public key cache a 1-entry FIFO cachev0.31.0
Users of the the ssh package seem to extremely commonly misuse the PublicKeyCallback API, assuming that the key passed in the last call before a connection is established is the key used for authentication. Some users then make authorization decisions based on this key. This property is not documented, and may not be correct, due to the caching behavior of the package, resulting in users making incorrect authorization decisions about the connection. This change makes the cache a one entry FIFO cache, making the assumed property, that the last call to PublicKeyCallback represents the key actually used for authentication, actually hold. Thanks to Damien Tournoud, Patrick Dawkins, Vince Parker, and Jules Duvivier from the Platform.sh / Upsun engineering team for reporting this issue. Fixes golang/go#70779 Fixes CVE-2024-45337 Change-Id: Ife7c7b4045d8b6bcd7e3a417bdfae370c709797f Reviewed-on: https://go-review.googlesource.com/c/crypto/+/635315 Reviewed-by: Roland Shoemaker <roland@golang.org> Auto-Submit: Gopher Robot <gobot@golang.org> Reviewed-by: Damien Neil <dneil@google.com> Reviewed-by: Nicola Murino <nicola.murino@gmail.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'ssh/server.go')
-rw-r--r--ssh/server.go15
1 files changed, 11 insertions, 4 deletions
diff --git a/ssh/server.go b/ssh/server.go
index c0d1c29..5b5ccd9 100644
--- a/ssh/server.go
+++ b/ssh/server.go
@@ -149,7 +149,7 @@ func (s *ServerConfig) AddHostKey(key Signer) {
}
// cachedPubKey contains the results of querying whether a public key is
-// acceptable for a user.
+// acceptable for a user. This is a FIFO cache.
type cachedPubKey struct {
user string
pubKeyData []byte
@@ -157,7 +157,13 @@ type cachedPubKey struct {
perms *Permissions
}
-const maxCachedPubKeys = 16
+// maxCachedPubKeys is the number of cache entries we store.
+//
+// Due to consistent misuse of the PublicKeyCallback API, we have reduced this
+// to 1, such that the only key in the cache is the most recently seen one. This
+// forces the behavior that the last call to PublicKeyCallback will always be
+// with the key that is used for authentication.
+const maxCachedPubKeys = 1
// pubKeyCache caches tests for public keys. Since SSH clients
// will query whether a public key is acceptable before attempting to
@@ -179,9 +185,10 @@ func (c *pubKeyCache) get(user string, pubKeyData []byte) (cachedPubKey, bool) {
// add adds the given tuple to the cache.
func (c *pubKeyCache) add(candidate cachedPubKey) {
- if len(c.keys) < maxCachedPubKeys {
- c.keys = append(c.keys, candidate)
+ if len(c.keys) >= maxCachedPubKeys {
+ c.keys = c.keys[1:]
}
+ c.keys = append(c.keys, candidate)
}
// ServerConn is an authenticated SSH connection, as seen from the