Skip to content

TLS private key written without enforcing 0600 permissions #379

Description

@forkwright

Finding

tls::save_identity writes the QUIC TLS private key with fs::write(key_path, key.secret_der()). On Linux fs::write creates the file with permissions determined by the process umask (commonly 0644), so a default umask of 0022 yields a world-readable private key. The certificate is written with the same call pattern.

Evidence

crates/syndesis/src/tls/mod.rs:107

fs::write(cert_path, &cert_bytes)

crates/syndesis/src/tls/mod.rs:108

fs::write(key_path, key.secret_der())

Neither call sets an explicit file mode, so both inherit the process umask.

Why this matters

When harmonia runs under a non-restrictive umask (the common case for systemd units inheriting the default), any local user or unprivileged app on the device can read the private key file. On a counter-surveillance phone OS this is a key-exfiltration path: a hostile local app reads the TLS identity, and combined with the always-accepting TofuVerifier it can impersonate the device and perform a real-time MitM against renderer connections, defeating transport authentication entirely.

Desired correction

Create the key file with std::fs::OpenOptions using mode(0o600) (via std::os::unix::fs::OpenOptionsExt), or call std::fs::set_permissions to 0600 immediately after writing. The certificate file may remain 0644.

Done when: a test verifies that after save_identity the key file has permissions 0600 regardless of the process umask.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions