CodeQL 文档

使用不安全的 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

点击查看 CodeQL 代码库中的查询

用于指定建立 SSH 连接配置的 ClientConfig 有一个字段 HostKeyCallback,该字段必须使用一个函数进行初始化,该函数用于验证服务器返回的主机密钥。

未正确验证服务器返回的主机密钥会为攻击者提供执行中间人 (MitM) 攻击的机会。成功的攻击可能会损害与服务器通信的信息的机密性和完整性。

ssh 包提供了预定义的回调函数 InsecureIgnoreHostKey,可在开发和测试期间使用。它接受任何提供的主机密钥。此回调函数或语义相似的回调函数不应在生产代码中使用。

建议

ClientConfigHostKeyCallback 字段应使用一个函数进行初始化,该函数根据允许列表验证主机密钥。如果密钥不在预定义的允许列表中,则必须终止连接并记录失败的安全操作。

当允许列表仅包含单个主机密钥时,可以使用 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),
	}
}

参考文献

  • ©2025GitHub 公司
  • 条款
  • 隐私