nixpkgs/pkgs/by-name/li/litestream/fix-cve-2024-41254.patch
ak2k 84cd68f555 litestream: fix CVE-2024-41254 by adding SSH host key verification
Apply patch from upstream commit f6c859061bfd7ccc2a21fcde3e9f0eb9ad98cd5e
by benbjohnson that adds optional SSH host key verification to SFTP
connections. This addresses CVE-2024-41254 where InsecureIgnoreHostKey()
was used unconditionally, allowing potential MITM attacks.

The patch adds a new `host-key-path` configuration option that allows
users to specify a file containing the SSH host key for verification.
When not specified, it maintains backward compatibility by falling back
to the insecure behavior.

Fixes: #388411
2025-07-02 18:14:07 -04:00

64 lines
2.0 KiB
Diff

diff --git a/cmd/litestream/main.go b/cmd/litestream/main.go
index 1234567..abcdefg 100644
--- a/cmd/litestream/main.go
+++ b/cmd/litestream/main.go
@@ -362,6 +362,7 @@ type ReplicaConfig struct {
Host string `yaml:"host"`
User string `yaml:"user"`
Password string `yaml:"password"`
KeyPath string `yaml:"key-path"`
+ HostKeyPath string `yaml:"host-key-path"`
// Encryption identities and recipients
@@ -664,6 +665,7 @@ func NewReplicaFromConfig(c *ReplicaConfig, dbc *DBConfig) (_ litestream.Replic
client.Password = password
client.Path = path
client.KeyPath = c.KeyPath
+ client.HostKeyPath = c.HostKeyPath
return client, nil
}
diff --git a/sftp/replica_client.go b/sftp/replica_client.go
index 30d8fa87..8b651e97 100644
--- a/sftp/replica_client.go
+++ b/sftp/replica_client.go
@@ -41,6 +41,7 @@ type ReplicaClient struct {
Password string
Path string
KeyPath string
+ HostKeyPath string
DialTimeout time.Duration
}
@@ -71,14 +72,28 @@ func (c *ReplicaClient) Init(ctx context.Context) (_ *sftp.Client, err error) {
// Build SSH configuration & auth methods
config := &ssh.ClientConfig{
- User: c.User,
- HostKeyCallback: ssh.InsecureIgnoreHostKey(),
- BannerCallback: ssh.BannerDisplayStderr(),
+ User: c.User,
+ BannerCallback: ssh.BannerDisplayStderr(),
}
if c.Password != "" {
config.Auth = append(config.Auth, ssh.Password(c.Password))
}
+ if c.HostKeyPath == "" {
+ config.HostKeyCallback = ssh.InsecureIgnoreHostKey()
+ } else {
+ buf, err := os.ReadFile(c.HostKeyPath)
+ if err != nil {
+ return nil, fmt.Errorf("cannot read sftp host key path: %w", err)
+ }
+
+ key, _, _, _, err := ssh.ParseAuthorizedKey(buf)
+ if err != nil {
+ return nil, fmt.Errorf("cannot parse sftp host key path: path=%s len=%d err=%w", c.HostKeyPath, len(buf), err)
+ }
+ config.HostKeyCallback = ssh.FixedHostKey(key)
+ }
+
if c.KeyPath != "" {
buf, err := os.ReadFile(c.KeyPath)
if err != nil {