Unverified Commit 7fd36ee8 authored by Aleksana's avatar Aleksana Committed by GitHub
Browse files

litestream: fix CVE-2024-41254 by adding SSH host key verification (#421926)

parents c16edd6d 84cd68f5
Loading
Loading
Loading
Loading
+64 −0
Original line number Diff line number Diff line
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 {
 No newline at end of file
+2 −1
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ buildGoModule rec {

  vendorHash = "sha256-sYIY3Z3VrCqbjEbQtEY7q6Jljg8jMoa2qWEB/IkDjzM=";

  patches = [ ./fix-cve-2024-41254.patch ];

  passthru.tests = { inherit (nixosTests) litestream; };

  meta = with lib; {
@@ -31,6 +33,5 @@ buildGoModule rec {
    license = licenses.asl20;
    homepage = "https://litestream.io/";
    maintainers = with maintainers; [ fbrs ];
    knownVulnerabilities = [ "CVE-2024-41254" ];
  };
}