Archived

This forum has been archived. Please start a new discussion on GitHub.

Clearing memory for sensitive data

Zeroc, Does ICE clear memory after returning from an invocation? For example, if ICE is used to transmit a password as a string is the memory cleared?

Thanks --Roland

Comments

  • marc
    marc Florida
    No, Ice does not clear memory before it releases such memory. This would decrease performance, and most applications don't need this.

    Perhaps the best solution would be to link with a library that implements free and delete so that memory is cleared?
  • Hi Marc, I understand the performance argument. I certainly wouldn't want all memory to be zero'd out at the expense of performance. I'm wondering if I can cast const away away then zero/clear memory. For example, I added a method called setPassword to your Hello demo.

    interface Hello
    {
    nonmutating void sayHello();
    void setPassword(string password);
    idempotent void shutdown();
    };

    Here is the implementation on Windows.

    void
    HelloI::setPassword(const ::std::string& password, const ::Ice::Current&)
    {
    // Assign the password...

    // Now zero out memory.
    SecureZeroMemory(&const_cast<::std::string&>(password)[0], password.size());
    }

    Would this actually be safe or are there multiple copies of the data made by the ICE runtime? If there are then obviousely this method wouldn't work.

    What I'm trying to eliminate is passwords being stored in the runtime? For example, if a customer sends a core dump, are they potentially sending username and passwords in cleartext? If I can't do the above with ICE then that implies that sensitive data needs to be encrypted outside of ICE if we want to mitigate this threat.

    Regards --Roland
  • marc
    marc Florida
    rhochmuth wrote: »
    Would this actually be safe or are there multiple copies of the data made by the ICE runtime? If there are then obviousely this method wouldn't work.

    I'm afraid this wouldn't work. Strings are not zero-copy in Ice, so there is an additional copy by the Ice runtime.
    rhochmuth wrote: »
    What I'm trying to eliminate is passwords being stored in the runtime? For example, if a customer sends a core dump, are they potentially sending username and passwords in cleartext? If I can't do the above with ICE then that implies that sensitive data needs to be encrypted outside of ICE if we want to mitigate this threat.

    Ice for C++ doesn't use a memory pool, so in theory, once the call returns the memory is released and the password should not be part of any core dump (except, of course, if the core dump is taken in the code path where the password is visible).

    However, I'm saying "in theory", because I really don't know if core dumps also include some memory that has already been released. I guess this depends both on the implementation of malloc/free, and on how core dumps are exactly generated.

    Also note that for Java and C#, we use memory pools for performance reasons. Even if we wouldn't use memory pools in Java and C#, I do not know how their virtual machines handle freed memory. However, this should really only matter if somebody sends you a core dump of the whole virtual machine, which would be rather unusual.

    We could in theory add a metadata directive to Slice, such as ["clear"], that directs the Ice runtime to clear memory for certain parameters after unmarshaling. If this is essential for your application, please contact us at info@zeroc.com to discuss this.
  • A core dump is basically a dump of all the CPU registers at the time of the crash, plus the contents of the data and stack segments of the process. Because the heap is typically fragmented, even if a string is free'd, it is highly unlikely that this will result in an adjustment of the segment pointer. In other words, if a process dumps core, the contents of any free'd strings are almost certain to show up in the core dump.

    For languages such as Java, things are worse: strings are immutable, so it's not possible to zero out a string--the string simply hangs around until the garbage collector reclaims it. But, even after that, the physical memory for the string will still be intact as part of the process until that memory is used for something else and gets overwritten as a result.

    I suspect that there is little we can do to mitigate this. Adding a metadata directive won't help much because, if the process dumps core at the wrong moment (which is entirely possible in the presence of threads), the memory contents will still make it into the core dump.

    Also, note that this issue is quite unrelated to Ice: even without Ice, if a process uses a password and dumps core at the wrong moment, the password will be in the core dump.

    Programs such as PGP go to quite some length to minimize the amount of time that an unencrypted password hangs around in memory. However, the password has to be left intact until it has been used and, during that time, the process is vulnerable if an attacker can provoke a core dump.

    There is really almost nothing Ice can do here. The only protection is what the OS provides (make it impossible for an unauthorized person to cause a process to dump core and disallow core dumps for sensitive processes, such as UNIX set-uid programs). Other than that, your only option is to minimize the amount of time an unencrypted password hangs around in memory. If you are worried about the amount of time that is added to that by the Ice run time, the best suggestion I have is to encrypt the password before giving it to the Ice run time.

    Cheers,

    Michi.
  • Hi Marc and Michi, Thanks for the detailed responses.

    I still think the metadata directive would be useful. We're using C++, but I guess there are implications with JAVA that I can't comment on. I would have hoped that JAVA would have a secure string and secure memory classes.

    I realize that it is impossible to address the issue completely. The best that can be done is to clear out memory as soon as the data is no longer required which minimizes the security threat window. It is a recommended practice by many.

    If I encrypt the sensitive data then my app would still have to decrypt and just after decryption the password would be available in cleartext, so a threat window still exists even with encryption, but it is a smaller window. However, the key to decrypt is required by the app and therefore also in memory and for someone with enough resources if the memory isn't cleared...

    Before I add the encryption would it be possible to use the zero-copy metadata directive and just a byte sequence instead of a string and clear memory using my earlier code? This would certainly be a much simpler approach and seems to align with what is common practice. If not, I'll need to make a decision on how important it is to address this type of security threat and make a decision on whether to apply encryption in our app or pursue a "clear" directive. Although it looks like the clear directive has some language interoperability concerns with at least JAVA which wouldn't map well with ICE and probably not worth pursuing.

    Regards --Roland
  • dwayne
    dwayne St. John's, Newfoundland
    rhochmuth wrote: »
    Before I add the encryption would it be possible to use the zero-copy metadata directive and just a byte sequence instead of a string and clear memory using my earlier code?

    For C++, if you use zero-copy then Ice will only create a single instance of the password byte sequence in memory on the server-side, which will be passed to your operation. If you clear that sequence, the password should be gone from memory.

    Regards,
    Dwayne