Skip to content

security concerns from NixOS #967

@different-error

Description

@different-error

Hello, consider the following questions from a nixpkgs maintainer:

Given the whole thing did not make sense to me I took a look at what they are doing with it. In the 4.0.0 release it seems to have 2 usages:

As one would expect with the static salt value, the encryption of configuration files is security theater with broken cryptography usages.

On fresh install to encrypt the configuration they first generate a passphrase, encrypt it using the salt as the key and save it. Once that is done they can encrypt the configuration using the generated passphrase.
When they need to open an existing configuration, they first look for the saved encrypted passphrase, decrypt it with the salt and then use the passphrase to decrypt the configuration.
I'm not sure what's the threat model here seems it seems unlikely that an attacker with the ability to capture the encrypted configuration file could not also capture the encrypted configuration file.

Even without considering the threat model, the way cryptography is being used is not something I would expect to find in any software and even less in one putting "privacy" in the center of the business model and relying extensively on cryptography to do its job. Yes that is not the code used to mount the tunnels but this is the sort of thing that is CVE worthy.

To explain a bit more:
The code generating the passphrase does not rely on CSRNG but it is seeded from the current time. That is a relatively small space to bruteforce especially since it is not unlikely that an attacker would have a rough idea of the creation date and/or modification time of the configuration file.

func generateKey() []byte {
min, max := 33, 126
key := make([]byte, 0, 32)
source := rand.NewSource(time.Now().UnixNano())
// #nosec G404 -- config encryption will go away after OSS
r := rand.New(source)
for i := 0; i < 32; i++ {
character := r.Intn(max-min) + min
key = append(key, byte(character))
}
return key
}

To encrypt the content they are relying on internal minimal library using AES GCM. However they are using MD5 as a key derivation function which is not meant for this usage (and well in 2025 MD5 as no place to be used in a cryptography-related context).

https://github.com/NordSecurity/nordvpn-linux/blob/4.0.0/internal/crypto.go#L13-L18

I suppose the KDF being used is not really that important since anyway they are using either a publicly known key or key generated with a cryptographically weak number generator.

I would have expected better practices for this kind of software.

Discussion found here. Your clarification would help a bunch! Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions