使用不安全的 HostKeyCallback 实现¶
ID: go/insecure-hostkeycallback
Kind: path-problem
Security severity: 8.2
Severity: warning
Precision: high
Tags:
- security
- external/cwe/cwe-322
Query suites:
- go-code-scanning.qls
- go-security-extended.qls
- go-security-and-quality.qls
用于指定建立 SSH 连接配置的 ClientConfig
有一个字段 HostKeyCallback
,该字段必须使用一个函数进行初始化,该函数用于验证服务器返回的主机密钥。
未正确验证服务器返回的主机密钥会为攻击者提供执行中间人 (MitM) 攻击的机会。成功的攻击可能会损害与服务器通信的信息的机密性和完整性。
ssh
包提供了预定义的回调函数 InsecureIgnoreHostKey
,可在开发和测试期间使用。它接受任何提供的主机密钥。此回调函数或语义相似的回调函数不应在生产代码中使用。
建议¶
ClientConfig
的 HostKeyCallback
字段应使用一个函数进行初始化,该函数根据允许列表验证主机密钥。如果密钥不在预定义的允许列表中,则必须终止连接并记录失败的安全操作。
当允许列表仅包含单个主机密钥时,可以使用 FixedHostKey
函数。
示例¶
以下示例显示了 InsecureIgnoreHostKey
的使用以及非生产代码中常用的不安全主机密钥回调函数实现。
package main
import (
"golang.org/x/crypto/ssh"
"net"
)
func main() {}
func insecureIgnoreHostKey() {
_ = &ssh.ClientConfig{
User: "username",
Auth: []ssh.AuthMethod{nil},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
}
func insecureHostKeyCallback() {
_ = &ssh.ClientConfig{
User: "username",
Auth: []ssh.AuthMethod{nil},
HostKeyCallback: ssh.HostKeyCallback(
func(hostname string, remote net.Addr, key ssh.PublicKey) error {
return nil
}),
}
}
下一个示例显示了使用实现允许列表的 FixedHostKey
的安全实现。
package main
import (
"golang.org/x/crypto/ssh"
"io/ioutil"
)
func main() {}
func secureHostKeyCallback() {
publicKeyBytes, _ := ioutil.ReadFile("allowed_hostkey.pub")
publicKey, _ := ssh.ParsePublicKey(publicKeyBytes)
_ = &ssh.ClientConfig{
User: "username",
Auth: []ssh.AuthMethod{nil},
HostKeyCallback: ssh.FixedHostKey(publicKey),
}
}
参考文献¶
Go 开发:package ssh。
常见弱点枚举:CWE-322。