Skip to content

Commit 533fb3f

Browse files
committed
ssh: fix source-address critical option bypass
Previously, CVE-2024-45337 fixed an authorization bypass for misused ssh server configurations; if any other type of callback is passed other than public key, then the source-address validation would be skipped. Fixes CVE-2026-46595 Fixes golang/go#79570 Change-Id: I08d86a961048a232c8672f23000e693ed5a0e2fd Reviewed-on: https://go-review.googlesource.com/c/crypto/+/781642 LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Neal Patel <nealpatel@google.com> Reviewed-by: Roland Shoemaker <roland@golang.org>
1 parent abbc44d commit 533fb3f

2 files changed

Lines changed: 45 additions & 0 deletions

File tree

ssh/server.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,13 @@ userAuthLoop:
837837
// considered verified and the callback must not run.
838838
perms, authErr = config.VerifiedPublicKeyCallback(s, pubKey, perms, algo)
839839
}
840+
if authErr == nil && perms != nil && perms.CriticalOptions != nil {
841+
if saco := perms.CriticalOptions[sourceAddressCriticalOption]; saco != "" {
842+
if err := checkSourceAddress(s.RemoteAddr(), saco); err != nil {
843+
authErr = err
844+
}
845+
}
846+
}
840847
}
841848
case "gssapi-with-mic":
842849
if authConfig.GSSAPIWithMICConfig == nil {

ssh/server_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,44 @@ func TestVerifiedPubKeyCallbackError(t *testing.T) {
669669
}
670670
}
671671

672+
func TestVerifiedPubKeyCallbackSourceAddress(t *testing.T) {
673+
c1, c2, err := netPipe()
674+
if err != nil {
675+
t.Fatalf("netPipe: %v", err)
676+
}
677+
defer c1.Close()
678+
defer c2.Close()
679+
680+
serverConf := &ServerConfig{
681+
PublicKeyCallback: func(conn ConnMetadata, key PublicKey) (*Permissions, error) {
682+
return nil, nil
683+
},
684+
VerifiedPublicKeyCallback: func(conn ConnMetadata, key PublicKey, permissions *Permissions, signatureAlgorithm string) (*Permissions, error) {
685+
return &Permissions{
686+
CriticalOptions: map[string]string{
687+
sourceAddressCriticalOption: "192.168.99.99",
688+
},
689+
}, nil
690+
},
691+
}
692+
serverConf.AddHostKey(testSigners["rsa"])
693+
694+
clientConf := ClientConfig{
695+
User: "user",
696+
Auth: []AuthMethod{
697+
PublicKeys(testSigners["rsa"]),
698+
},
699+
HostKeyCallback: InsecureIgnoreHostKey(),
700+
}
701+
702+
go NewServerConn(c1, serverConf)
703+
704+
_, _, _, err = NewClientConn(c2, "", &clientConf)
705+
if err == nil {
706+
t.Fatal("client login succeed with VerifiedPublicKeyCallback returning mismatching source-address")
707+
}
708+
}
709+
672710
func TestVerifiedPublicCallbackPartialSuccessBadUsage(t *testing.T) {
673711
c1, c2, err := netPipe()
674712
if err != nil {

0 commit comments

Comments
 (0)