Missing SSH host key verification
ID |
go.missing_ssh_host_key_verification |
Severity |
critical |
Resource |
Misconfiguration |
Language |
Go |
Tags |
CWE:322, NIST.SP.800-53, OWASP:2021:A1, OWASP:2021:A5, PCI-DSS:6.5.4 |
Description
The application establishes SSH connections without verifying the host key, which can expose it to man-in-the-middle (MITM) attacks.
Rationale
In Go, using the golang.org/x/crypto/ssh
package, it is common to configure SSH clients with a HostKeyCallback
. Skipping host key verification (for example, using ssh.InsecureIgnoreHostKey()
) disables validation of the server’s identity. This allows attackers to intercept or tamper with SSH communications.
package main
import (
"golang.org/x/crypto/ssh"
)
func main() {
// Insecure: host key verification is skipped
config := &ssh.ClientConfig{
User: "user",
Auth: []ssh.AuthMethod{
ssh.Password("password"),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
client, err := ssh.Dial("tcp", "example.com:22", config)
if err != nil {
panic(err)
}
defer client.Close()
}
Using ssh.InsecureIgnoreHostKey()
may seem convenient during development, but it removes all guarantees that the server being connected to is legitimate, creating a significant security risk.
Remediation
To remediate, always validate the server’s host key. This can be done by storing known host keys and using a proper HostKeyCallback
function that checks the server key against the known list.
package main
import (
"fmt"
"io/ioutil"
"golang.org/x/crypto/ssh"
)
func main() {
// Load known_hosts file
knownHosts, err := ioutil.ReadFile("/home/user/.ssh/known_hosts")
if err != nil {
panic(err)
}
hostKeyCallback, err := ssh.ParseKnownHosts(knownHosts)
if err != nil {
panic(err)
}
config := &ssh.ClientConfig{
User: "user",
Auth: []ssh.AuthMethod{
ssh.Password("password"),
},
HostKeyCallback: hostKeyCallback,
}
client, err := ssh.Dial("tcp", "example.com:22", config)
if err != nil {
panic(err)
}
defer client.Close()
fmt.Println("SSH connection established with verified host key")
}
Key points for remediation in Go:
- Never use ssh.InsecureIgnoreHostKey()
in production code.
- Maintain a known_hosts
file or an equivalent trusted store of host keys.
- Implement a HostKeyCallback
function that validates the server key against the trusted store.
References
-
CWE-862 : Key Exchange without Entity Authentication.
-
OWASP - Top 10 2021 Category A01 : Broken Access Control.