#1907 Process memory protection for Mono

KeePass_2.x
closed
nobody
None
5
2014-08-16
2014-07-28
No

I can understand that Keepass needs to retain the passphrase in memory when the app is in use, but if the database is closed or locked and requires me to retype my passphrase to use it, I would have assumed that Keepass was wiping my passphrase from memory. However, that is not the case.

You can prove this to yourself:

  • Create a new database, use a password of: open_sesame
  • Close keepass
  • Open keepass again, unlock the database
  • Close or Lock the database.
  • run: sudo gcore -o keepass.core pgrep -f keepass
  • run: strings keepass.core.PID_OF_KEEPASS | grep open_sesame
  • Notice that there is three copies of the passphrase in the core dump.

My passphrase is retained in memory until I completely close keepass.

Tested on keepass 2.27

Discussion

  • Ryan McGuire

    Ryan McGuire - 2014-07-28

    I messed up the formatting of those commands, they should read:

    sudo gcore -o keepass.core `pgrep -f keepass`
    strings keepass.core.PID_OF_KEEPASS | grep open_sesame

     
  • Paul

    Paul - 2014-07-29

    KeePass retains session data, last view etc, but the passphrase should not be there. Are you sure it's the passphrase?

    cheers, Paul

     
  • Ryan McGuire

    Ryan McGuire - 2014-07-29

    Very sure. Thanks for looking into it.

     
  • Paul

    Paul - 2014-07-29

    It may be an issue with mono memory management rather than KeePass. KeePass wipes sensitive memory before releasing it.
    http://keepass.info/help/base/security.html#secmemprot

    cheers, Paul

     
  • Dominik Reichl

    Dominik Reichl - 2014-07-29

    The Mono page [1] states: 'There is partial support for ProtectedData and ProtectedMemory on Mono. On Windows Mono will use DPAPI (Data Protection API) for increased interoperability, while it will use its own implementation on other operating systems.'

    By this, I assumed that Mono would implement an own memory protection method on Unix-like systems. However, this apparently is not true. Looking into the Mono source code ([2] and [3]), Mono seems to implement no memory protection at all for Unix-like systems. For the SecureString class they made an attempt, but then removed the encryption with the comment 'It somehow causes nunit test breakage'.

    As process memory protection is pretty important for KeePass, I'm going to develop an own memory protection method for Unix-like systems. Unfortunately, this will be less effective, because KeePass needs to keep the keys in its own process memory (in contrast to the situation on Windows, where Windows keeps the key in a safer memory location).

    Moving to open feature requests.

    Best regards,
    Dominik

    [1] http://www.mono-project.com/Cryptography
    [2] https://github.com/mono/mono/blob/master/mcs/class/System.Security/System.Security.Cryptography/ProtectedMemory.cs
    [3] https://github.com/mono/mono/blob/master/mcs/class/corlib/System.Security/SecureString.cs

     
  • Dominik Reichl

    Dominik Reichl - 2014-07-29
    • summary: Passphrase retained in memory even when database is 'locked' or 'closed' --> Process memory protection for Mono
     
  • Dominik Reichl

    Dominik Reichl - 2014-07-29

    Ticket moved from /p/keepass/bugs/1273/

     
  • David Lechner

    David Lechner - 2014-07-29

    I have a request if you are going to implement your own memory protection. Can you make it extensible? If you are able to do this, I could write a plugin that uses gnome keyring as the storage. Gnome keyring has its own special memory functions that are safer like windows ("protects(s) against... Reading passwords from memory after the user had logged out, or from the swap area of the disk. "1).

     
    Last edit: David Lechner 2014-07-29
  • Dominik Reichl

    Dominik Reichl - 2014-07-29

    Ok, I'll make it extensible.

     
  • Ryan McGuire

    Ryan McGuire - 2014-07-30

    This seems to be an issue on Windows 8 as well. I did the same repro steps as above, and took a core dump by going to the task manager, right clicking the keepass process, selecting "Create dump file" and then copied that file to my Linux computer and ran strings on it and the password was contained in it.

     
  • Dominik Reichl

    Dominik Reichl - 2014-07-30

    No, on Windows 8 the memory protection works fine.

    Some operations result in unencrypted data in memory. This is normal and cannot be prevented; for details, see
    http://keepass.info/help/base/security.html#secmemprot

    Best regards,
    Dominik

     
  • Ryan McGuire

    Ryan McGuire - 2014-07-30

    I read that, specifically "KeePass erases all security-critical memory when it's not needed anymore." Surely closing the database is one of those times where "it's not needed anymore."

     
  • Paul

    Paul - 2014-07-30

    Yes, that is one of the times. In Windows KeePass uses DPAPI to store keys and these are encrypted areas so you should never see raw passwords, let alone be able to dump them. Are you sure you have not stored the password in plain text somewhere?

    cheers, Paul

     
  • Ryan McGuire

    Ryan McGuire - 2014-07-30

    This is a fresh database. Here's the full repro steps:

    Open Keepass
    Create New Database
    Use master password: ren_and_stimpy
    Save the database
    Close the database
    Open Task manager, right click Keepass, select 'Create Dump File'
    On Linux, copy the file, and run: strings KeePass.DMP | grep ren_and_stimpy. - see about 11 instances of the password in the dump.

     
  • Dominik Reichl

    Dominik Reichl - 2014-07-30

    This is expected. In the 'Create Composite Master Key' dialog (shown during database creation), there's a password quality estimation. As documented on [1], computing quality estimations results in unencrypted data in process memory.

    Best regards,
    Dominik

    [1] http://keepass.info/help/base/security.html#secmemprot

     
  • Ryan McGuire

    Ryan McGuire - 2014-07-30

    ah, I see, confirmed that it doesn't retain it on a second opening (on windows, at least).

     
  • Dominik Reichl

    Dominik Reichl - 2014-07-31

    I've now finished adding a process memory protection for Unix-like systems.

    Here's the latest development snapshot for testing (including modified source code files):
    http://keepass.info/filepool/KeePass_140731.zip

    David, in order to provide a custom memory protection method via a plugin, assign a PbCryptDelegate to ProtectedBinary.ExtCrypt. ProtectedString and SecureEdit use ProtectedBinary internally and thus will use the same protection automatically. The first two parameters of the delegate should be self-explanatory; on the third: each ProtectedBinary object has a unique (per process) ID, which you get through this parameter; this can e.g. be used as initialization vector / nonce for some encryption modes (like I did in the new memory protection for Unix-like systems, which uses Salsa20 with a process-static random key and the object ID as nonce).

    Best regards,
    Dominik

     
  • Dominik Reichl

    Dominik Reichl - 2014-07-31
    • status: open --> closed
     

Log in to post a comment.