[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-frameworks-devel
Subject:    Re: Password field security and information leaking
From:       Albert Astals Cid <aacid () kde ! org>
Date:       2018-10-14 16:08:57
Message-ID: 2200101.N9T67O8W1G () xps
[Download RAW message or body]

El diumenge, 14 d'octubre de 2018, a les 11:19:17 CEST, Ivan Čukić va escriure:
> Hi all,
> 
> 
> We are using QLineEdit (and QML equivalent) all over KDE for passwords. This 
> is an issue for types of attacks that extract raw process memory because the 
> passwords can be leaked.
> 
> QLineEdit stores the current value as plain text in a QString. Which means 
> that while the password entry is shown in the screen, the password is stored 
> in memory for all to see (problem 1).
> 
> When the QLineEdit is destroyed, so is the QString. But, while the data buffer 
> is 'deleted', its contents remain in memory until some other dynamically 
> allocated object is created in the same memory space and overwrites the data - 
> this is because QString does not zero-out its buffer on destruction. This 
> means that the passwords remain in memory for much longer than needed (problem 
> 2).
> 
> Because of string reallocation on resizing, it is quite possible that, while 
> the user is typing the password, that the string will be resized/reallocated 
> at least once. This means that partial passwords (data from the buffer in the 
> string before reallocation which is not zeroed-out) will remain in memory 
> until something else overwrites them (problem 3).
> 
> All this memory can end up written to the hdd/ssd if the application is moved 
> to swap by the OS (problem 4).
> 
> Transporting passwords via DBus (KWallet) is the problem 5 (guessing there's 
> no need to explain this one in more detail).
> 
> 
> Potential solutions:
> 
> Problem 2 is easily solved in Qt by having QLineEdit zero-out the string data 
> on destruction if the line edit is used as a password entry. I've submitted a 
> patch for this [1]. Another additional change that can be applied to QLineEdit 
> is to call QString::reserve(50-or-something) when the line edit is used as a 
> password field to minimize the possibility of problem 3 occurring for most 
> use-cases.
> 
> Other problems are more difficult to solve. They need a custom component (from 
> what I can tell).
> 
> Namely, the least a proper password entry component could do is to use a 
> custom QString-like class which zeroes-out buffers before deleting them (on 
> reallocation and destruction), and which tells the OS that the value contents 
> should never be swapped. There is a class in QCA that can be used for this 
> (SecureArray, based on botan::SecureVector).
> 
> Having a password entry component that uses a secure buffer like SecureArray 
> would minimize the time the entered password is in memory to only while the 
> component is shown (problem 1).
> 
> The only remaining problems are 1 and 5.
> 
> Problem 1 can not be completely solved. If the password data is kept in memory 
> encrypted, the key for decryption needs to also be somewhere so that the 
> program can get the actual password instead of the encrypted version.
> 
> Still, it would be an improvement over the current situation because the 
> encryption password would be some random array of bytes, and the encrypted 
> passwords would appear as random arrays of bytes (when encryption is good, 
> encrypted data looks random). Which means that any attacks with the aim of 
> extracting the password data couldn't be based on text-processing - they would 
> need quite some effort of analyzing memory layout to find both the key and the 
> password in order to decrypt it.

Is this a problem at all? 
I mean, by default applications can't read other applications memory so the only one \
that can try this kind of attacks is the root user. 

If your system is compromised to the fact that root is evil you have lost already, \
surely root can install a key logger or something that will make it easy for her to \
snoop your passwords than having the grep the memory for them, no? (Well on X11 any \
application can install a keylogger but let's assume you're under Wayland :D)

> Now comes the most interesting part (IMO). which solves problem 5 and also 
> influences the previous issue of having the decryption key in memory.
> 
> We can use a stream cipher to encrypt the password in memory. This means that 
> the password characters can be encrypted one by one as the user types them in 
> - no need to have the whole password unencrypted in memory at any point in 
> time during password entry.
> 
> If we use public/private key encryption, where the password entry is in one 
> process, and the password usage is in another, only the password usage process 
> will be able to decrypt the password (and, again, there will be no need to the 
> whole password to be decrypted at once - just one character at a time can be 
> sufficient in many use-cases). This means that the attacker will need to have 
> either access to the memory spaces of both processes, or to hit a very narrow 
> window in the 'usage process' between 'I got the password' and 'I used the 
> password and zeroed-out the data'.
> 
> The pub/priv key exchange can be done mostly securely using Diffie-Hellman 
> protocol similar to what the Secret Service API [2] does. The only attack 
> vector would be to replace the normal dbus server with a malicious one. In 
> that case (having a malicious system component), I'd say the systems is 
> already compromised and that we can not do anything to protect the user.
> 
> 
> Thoughts?

AFAIR there's private dbus through apparmor, that'd be a simpler fix, unfortunately \
apparmor is not default on all distros so doesn't really solve much for us.

Not sure if any other dbus or kernel security enhacements implement or plan to \
implement this.

The problem i see with your implementation is that it secures the transport, but who \
cares about that? At this point i can just go to kwalletd and write a program that \
will say "Hey, I'm the network manager, give me this password" and there's no way for \
kwalletd to figure out if this is true or not, so it'll just give that program access \
to all my passwords without any need to snoop at the transport layer.

I've been thinking about that for a while and the only solution i've found is signing \
the binaries.

Cheers,
  Albert

> Cheers,
> Ivan
> 
> [1] https://codereview.qt-project.org/#/c/242202/
> [2] https://specifications.freedesktop.org/secret-service/index.html
> 
> 
> 
> dr Ivan Čukić
> KDE, ivan.cukic@kde.org, https://cukic.co/
> gpg key fingerprint: 8FE4 D32F 7061 EA9C 8232  07AE 01C6 CE2B FF04 1C12
> 
> 
> 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic