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

ak2k 84cd68f5 5a7fb841

+66 -1
+64
pkgs/by-name/li/litestream/fix-cve-2024-41254.patch
··· 1 + diff --git a/cmd/litestream/main.go b/cmd/litestream/main.go 2 + index 1234567..abcdefg 100644 3 + --- a/cmd/litestream/main.go 4 + +++ b/cmd/litestream/main.go 5 + @@ -362,6 +362,7 @@ type ReplicaConfig struct { 6 + Host string `yaml:"host"` 7 + User string `yaml:"user"` 8 + Password string `yaml:"password"` 9 + KeyPath string `yaml:"key-path"` 10 + + HostKeyPath string `yaml:"host-key-path"` 11 + 12 + // Encryption identities and recipients 13 + @@ -664,6 +665,7 @@ func NewReplicaFromConfig(c *ReplicaConfig, dbc *DBConfig) (_ litestream.Replic 14 + client.Password = password 15 + client.Path = path 16 + client.KeyPath = c.KeyPath 17 + + client.HostKeyPath = c.HostKeyPath 18 + return client, nil 19 + } 20 + 21 + diff --git a/sftp/replica_client.go b/sftp/replica_client.go 22 + index 30d8fa87..8b651e97 100644 23 + --- a/sftp/replica_client.go 24 + +++ b/sftp/replica_client.go 25 + @@ -41,6 +41,7 @@ type ReplicaClient struct { 26 + Password string 27 + Path string 28 + KeyPath string 29 + + HostKeyPath string 30 + DialTimeout time.Duration 31 + } 32 + 33 + @@ -71,14 +72,28 @@ func (c *ReplicaClient) Init(ctx context.Context) (_ *sftp.Client, err error) { 34 + 35 + // Build SSH configuration & auth methods 36 + config := &ssh.ClientConfig{ 37 + - User: c.User, 38 + - HostKeyCallback: ssh.InsecureIgnoreHostKey(), 39 + - BannerCallback: ssh.BannerDisplayStderr(), 40 + + User: c.User, 41 + + BannerCallback: ssh.BannerDisplayStderr(), 42 + } 43 + if c.Password != "" { 44 + config.Auth = append(config.Auth, ssh.Password(c.Password)) 45 + } 46 + 47 + + if c.HostKeyPath == "" { 48 + + config.HostKeyCallback = ssh.InsecureIgnoreHostKey() 49 + + } else { 50 + + buf, err := os.ReadFile(c.HostKeyPath) 51 + + if err != nil { 52 + + return nil, fmt.Errorf("cannot read sftp host key path: %w", err) 53 + + } 54 + + 55 + + key, _, _, _, err := ssh.ParseAuthorizedKey(buf) 56 + + if err != nil { 57 + + return nil, fmt.Errorf("cannot parse sftp host key path: path=%s len=%d err=%w", c.HostKeyPath, len(buf), err) 58 + + } 59 + + config.HostKeyCallback = ssh.FixedHostKey(key) 60 + + } 61 + + 62 + if c.KeyPath != "" { 63 + buf, err := os.ReadFile(c.KeyPath) 64 + if err != nil {
+2 -1
pkgs/by-name/li/litestream/package.nix
··· 23 23 24 24 vendorHash = "sha256-sYIY3Z3VrCqbjEbQtEY7q6Jljg8jMoa2qWEB/IkDjzM="; 25 25 26 + patches = [ ./fix-cve-2024-41254.patch ]; 27 + 26 28 passthru.tests = { inherit (nixosTests) litestream; }; 27 29 28 30 meta = with lib; { ··· 31 33 license = licenses.asl20; 32 34 homepage = "https://litestream.io/"; 33 35 maintainers = with maintainers; [ fbrs ]; 34 - knownVulnerabilities = [ "CVE-2024-41254" ]; 35 36 }; 36 37 }