Repository: go
Issue: x/vuln: false negative for GO-2024-3321
Labels: NeedsInvestigation,vulncheck or vulndb

### Go version

go1.23.5

### Output of `go env` in your module/workspace:

```shell
GO111MODULE=''
GOARCH='amd64'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOOS='linux'
GOROOT='/usr/local/go'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.23.5'
GODEBUG=''
GOTELEMETRY='local'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='0'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build753288169=/tmp/go-build -gno-record-gcc-switches
```

### What did you do?

Ran govulncheck on the sample code below (https://pkg.go.dev/golang.org/x/crypto/ssh#ServerConn example, with a `fmt.Println` added):
 
```go
package main
 
import (
       "fmt"
       "log"
       "net"
       "os"
       "sync"
 
       "golang.org/x/crypto/ssh"
       "golang.org/x/crypto/ssh/terminal"
)
 
func main() {
       // Public key authentication is done by comparing
       // the public key of a received connection
       // with the entries in the authorized_keys file.
       authorizedKeysBytes, err := os.ReadFile("authorized_keys")
       if err != nil {
              log.Fatalf("Failed to load authorized_keys, err: %v", err)
       }
 
       authorizedKeysMap := map[string]bool{}
       for len(authorizedKeysBytes) > 0 {
              pubKey, _, _, rest, err := ssh.ParseAuthorizedKey(authorizedKeysBytes)
              if err != nil {
                     log.Fatal(err)
              }
 
              authorizedKeysMap[string(pubKey.Marshal())] = true
              authorizedKeysBytes = rest
       }
 
       // An SSH server is represented by a ServerConfig, which holds
       // certificate details and handles authentication of ServerConns.
       config := &ssh.ServerConfig{
              // Remove to disable public key auth.
              PublicKeyCallback: func(c ssh.ConnMetadata, pubKey ssh.PublicKey) (*ssh.Permissions, error) {   // <<< Affected by the CVE and called
                     fmt.Printf("received key: %s\n", ssh.FingerprintSHA256(pubKey))
                     if authorizedKeysMap[string(pubKey.Marshal())] {
                           return &ssh.Permissions{
                                  // Record the public key used for authentication.
                                  Extensions: map[string]string{
                                         "pubkey-fp": ssh.FingerprintSHA256(pubKey),
                                  },
                           }, nil
                     }
                     return nil, fmt.Errorf("unknown public key for %q", c.User())
              },
       }
 
       privateBytes, err := os.ReadFile("hostkey")
       if err != nil {
              log.Fatal("Failed to load private key: ", err)
       }
 
       private, err := ssh.ParsePrivateKey(privateBytes)
       if err != nil {
              log.Fatal("Failed to parse private key: ", err)
       }
       config.AddHostKey(private)
 
       // Once a ServerConfig has been configured, connections can be
       // accepted.
       listener, err := net.Listen("tcp", "0.0.0.0:2022")
       if err != nil {
              log.Fatal("failed to listen for connection: ", err)
       }
       nConn, err := listener.Accept()
       if err != nil {
              log.Fatal("failed to accept incoming connection: ", err)
       }
 
       // Before use, a handshake must be performed on the incoming
       // net.Conn.
       conn, chans, reqs, err := ssh.NewServerConn(nConn, config)
       if err != nil {
              log.Fatal("failed to handshake: ", err)
       }
       log.Printf("logged in with key %s", conn.Permissions.Extensions["pubkey-fp"])
}
```

### What did you see happen?

Program output (when connected to using the Linux SSH client):
```
$ go run .
received key: SHA256:bh9pEcEmRfexTHJqZk263fTJCGqwiZarIV7B8fWwif8
received key: SHA256:QxTUMyd5Rwm9eoBoasz9yyTj4rm7K5dUOJ0oQvp6Y4w
2025/01/25 09:05:56 logged in with key SHA256:QxTUMyd5Rwm9eoBoasz9yyTj4rm7K5dUOJ0oQvp6Y4w
```
 
govulncheck output:
```
Fetching vulnerabilities from the database...
 
Checking the code against the vulnerabilities...
 
The package pattern matched the following root package:
  cve-2024-45337.test/F001/bin
Govulncheck scanned the following 4 modules and the go1.23.5 standard library:
  cve-2024-45337.test/F001/bin
  golang.org/x/crypto@v0.30.0
  golang.org/x/sys@v0.29.0
  golang.org/x/term@v0.27.0
 
=== Symbol Results ===
 
No vulnerabilities found.
 
=== Package Results ===
 
Vulnerability #1: GO-2024-3321
    Misuse of ServerConfig.PublicKeyCallback may cause authorization bypass in
    golang.org/x/crypto
  More info: https://pkg.go.dev/vuln/GO-2024-3321
  Module: golang.org/x/crypto
    Found in: golang.org/x/crypto@v0.30.0
    Fixed in: golang.org/x/crypto@v0.31.0
 
=== Module Results ===
 
No other vulnerabilities found.
 
Your code is affected by 0 vulnerabilities.
This scan also found 1 vulnerability in packages you import and 0
vulnerabilities in modules you require, but your code doesn't appear to call
these vulnerabilities.
```

### What did you expect to see?

The sample code is vulnerable to GO-2024-3321, as far as I can tell:
- uses golang.org/x/crypto v0.30.0
- serves SSH connections via ssh.NewServerConn and specifies a PublickeyCallback
 
Whilst the sample program does not misuse the callback, it potentially could. Based on the OSV record, the govulncheck seeks to determine whether ServerConfig.PublickeyCallback is executed (or reachable from main via call graph analysis). It clearly is but the report states otherwise.