476

I just realized that, in any language, when you save a password in a variable, it is stored as plain text in the memory.

I think the OS does its job and forbids processes from accessing each other's allocated memory. But I also think this is somehow bypassable. So I wonder if it is really safe and if there is a safer way to store passwords to ensure that foreign processes can't access them.

I didn't specify the OS or the language because my question is quite general. This is rather a computer literacy question than a specific purpose one.

9
  • 65
    This is actually the weakness of encryption. Any non encrypted value or waiting to be encrypted is stored in memory in plain text. Commented Jan 14, 2013 at 19:33
  • 4
    You might find some useful background in this question on Programmers.
    – Blrfl
    Commented Jan 14, 2013 at 21:03
  • 10
    I remember article on Slashdot about a forensics technique exploiting DRAM fade latency: move RAM chips from a running machine to a different one quickly enough (the number was well within human ability) and you can easily dump the whole content.
    – SF.
    Commented Jan 14, 2013 at 23:41
  • 1
    While other answers cover the "Safe as..." nuances well, if you are concerned, your platform/libraries may have a SecureString, or similar designed to minimize the risk. Such a construct might overwrite it's own memory as soon as you indicate you are done with it, as well as manage nuances of copies of itself introduced by garbage collection, etc.
    – DanO
    Commented Jan 15, 2013 at 0:15
  • 12
    A good safety precaution is to overwrite the variable containing the password as soon as possible (easier in C/C++ than Java) and instead work with a derived key (e.g. generated using PBKDF2).
    – Omar Kohl
    Commented Jan 15, 2013 at 11:20

14 Answers 14

498
+50

You are touching a sore point…

Historically, computers were mainframes where a lot of distinct users launched sessions and process on the same physical machine. Unix-like systems (e.g. Linux), but also VMS and its relatives (and this family includes all Windows of the NT line, hence 2000, XP, Vista, 7, 8...), have been structured in order to support the mainframe model.

Thus, the hardware provides privilege levels. A central piece of the operating system is the kernel which runs at the highest privilege level (yes, I know there are subtleties with regards to virtualization) and manages the privilege levels. Applications run at a lower level and are forcibly prevented by the kernel from reading or writing each other's memory. Applications obtain RAM by pages (typically 4 or 8 kB) from the kernel. An application which tries to access a page belonging to another application is blocked by the kernel, and severely punished ("segmentation fault", "general protection fault", …).

When an application no longer needs a page (in particular when the application exits), the kernel takes control of the page and may give it to another process. Modern operating systems "blank" pages before giving them back, where "blanking" means "filling with zeros". This prevents leaking data from one process to another. Note that Windows 95/98/Millennium did not blank pages, and leaks could occur… but these operating system were meant for a single user per machine.

Of course, there are ways to escape the wrath of the kernel: a few doorways are available to applications which have "enough privilege" (not the same kind of privileges than above). On a Linux system, this is ptrace(). The kernel allows one process to read and write the memory of the other, through ptrace(), provided that both processes run under the same user ID, or that the process which does the ptrace() is a "root" process. Similar functionality exists in Windows.

The bottom-line is that passwords in RAM are no safer than what the operating system allows. By definition, by storing some confidential data in the memory of a process, you are trusting the operating system for not giving it away to third parties. The OS is your friend, because if the OS is an enemy then you have utterly lost.


Now comes the fun part. Since the OS enforces a separation of process, many people have tried to find ways to pierce these defenses. And they found a few interesting things…

  • The "RAM" which the applications see is not necessarily true "memory". The kernel is a master of illusions, and gives pages that do not necessarily exist. The illusion is maintained by swapping RAM contents with a dedicated space on the disk, where free space is present in larger quantities; this is called virtual memory. Applications need not be aware of it, because the kernel will bring back the pages when needed (but, of course, disk is much slower than RAM). An unfortunate consequence is that some data, purportedly held in RAM, makes it to a physical medium where it will stay until overwritten. In particular, it will stay there if the power is cut. This allows for attacks where the bad guy grabs the machine and runs away with it, to inspect the data later on. Or leakage can occur when a machine is decommissioned and sold on eBay, and the sysadmin forgot to wipe out the disk contents.

    Linux provides a system called mlock() which prevents the kernel from sending some specific pages to the swap space. Since locking pages in RAM can deplete available RAM resources for other process, you need some privileges (root again) to use this function.

    An aggravating circumstance is that it is not necessarily easy to keep track of where your password is really in RAM. As a programmer, you access RAM through the abstraction provided by the programming language. In particular, programming languages which use Garbage Collection may transparently copy objects in RAM (because it really helps for many GC algorithms). Most programming languages are thus impacted (e.g. Java, C#/.NET, Javascript, PHP, … the list is almost endless).

  • Hibernation brings back the same issues, with a vengeance. By nature, hibernation must write the whole RAM to the disk -- this may include pages which were mlocked, and even the contents of the CPU registers. To avoid leaks through hibernation, you have to resort to drastic measures like encrypting the whole disk -- this naturally implies typing the unlock password whenever you awake the machine.

  • The mainframe model assumes that it can run several process which are hostile to each other, and yet maintain perfect peace and isolation. Modern hardware makes that very difficult. When two process run on the same CPU, they share some resources, including cache memory; memory accesses are much faster in the cache than elsewhere, but cache size is very limited. This has been exploited to recover cryptographic keys used by one process, from another. Variants have been developed which use other cache-like resources, e.g. branch prediction in a CPU. While research on that subject concentrates on cryptographic keys, which are high-value secrets, it could really apply to just any data.

    On a similar note, video cards can do Direct Memory Access. Whether DMA cannot be abused to read or write memory from other process depends on how well undocumented hardware, closed-source drivers and kernels collaborate to enforce the appropriate access controls. I would not bet my last shirt on it…


Conclusion: yes, when you store a password in RAM, you are trusting the OS for keeping that confidential. Yes, the task is hard, even nigh impossible on modern systems. If some data is highly confidential, you really should not use the mainframe model, and not allow potentially hostile entities to run their code on your machine.

(Which, by the way, means that hosted virtual machines and cloud computing cannot be ultimately safe. If you are serious about security, use dedicated hardware.)

14
  • 41
    "virtual machines and cloud computing cannot be ultimately safe". I've always been skeptical about cloud computing. Commented Jan 14, 2013 at 22:07
  • 61
    There is one more point to make. Somewhere, at some time, for some length of time, the plaintext simply must reside in "RAM". The entire exercise becomes rather pointless if the plaintext is never exposed to anyone anywhere. The upshot is that RAM, which is ostensibly never persisted and can be flagged as "protected", is about as safe as you'll get within the bounds of a computer system. Your point holds, however, that memory (and OS protections of same) are only regarded as safe because the alternative is not to use computers at all.
    – KeithS
    Commented Jan 14, 2013 at 23:13
  • 5
    To minimise the exposure of the sensitive data as clear text, various languages provide wrappers that make it easier to use Operating System facilities to prevent paging out. See e.g. .Net SecureString. However, this only mitigates the problem, doesn't solve it.
    – skolima
    Commented Jan 15, 2013 at 10:52
  • 2
    A note about hibernation - if the file itself is encrypted (swap on dm-crypt for example) then password stored there is encrypted as well - and DMA - Firewire often allow DMA from devices to access the RAM (IOMMU would protect against it). Commented Jan 15, 2013 at 11:10
  • 5
    I'd like to point out that, on Linux at least, mlock doesn't require root priv. There is, however, a strict limitation on how much memory you can lock if you're not root.
    – kestrel
    Commented Mar 18, 2013 at 15:19
58

I think the OS do his jobs and avoid processes to access other's allocated memory. But I think this is somehow doable.

Yes, it is possible to access the memory of another process. On Windows, this amounts to having SE_DEBUG_PRIVILEGE and using ReadProcessMemory() to extract the information you want.

You can do the same thing from a Windows Driver, although it is a tad harder to get right due to some complications with what memory is currently paged in to the lower half.

In either case, you need to have access to an administrative account, or a process incorrectly assigned SE_DEBUG_PRIVILEGE, or a process with this privilege that can be persuaded to do what you need.

So, it comes down to ensuring nobody can escalate to obtain these privileges. More realistically, we ensure only trusted users can have these privileges. If you have access to an administrative account, you can quite easily read a password straight out of another account's processes' memory.

Under linux, you can achieve the same thing with ptrace() and the PTRACE_PEEK_DATA option.

You might ask why these functions exist in the first place? Actually, they're incredibly handy for debugging processes. Conceivably, this is something an administrator user may wish to do. By constrast, normal users should not need to and should be isolated from each other.

This is why people have advised, for some time, that running everything under the Administrator account is generally not a great idea.

6
  • 2
    Thank you for this concise explanation for both Windows and GNU/Linux (I guess this values for other Unix systems as well). Commented Jan 14, 2013 at 20:54
  • 3
    @AntoinePinsard yes, if they implement ptrace it is highly likely!
    – user2213
    Commented Jan 14, 2013 at 21:04
  • 4
    On win you can read the memory of other processes running on the same user if if you don't have special privileges. Commented Jan 14, 2013 at 21:06
  • 4
    @Code true. I'm not sure any OS can defend you against yourself though!
    – user2213
    Commented Jan 14, 2013 at 21:24
  • 2
    @Sadaluk The real problem occurs when code running under your account is not run by you. Think scripts calling into native libraries, buffer overflow exploits, ...
    – user
    Commented Jan 14, 2013 at 22:19
44

I work in the consumer electronics arena and security here is somewhat different than in the server environment. Here we have to assume that the product is in a hostile environment. So for subscriber management purposes keys are kept secure. The first line of defence is that the SoC has hidden registers that even the operating system can't actually access, they are burnt in at manufacture time and chip-fuses are blown which prevent access. Also we don't see keys ourselves because that would be insecure on the production floor, instead they are pre-packaged with a batch key that we don't know, only the chip vendor and person who created the key knows that (the master key can be destroyed after use in the chip). Once the chip is loaded with secrets then it can be locked and never* unlocked.

If you can't access the keys then how do you decrypt anything? With a cryptographic co-processor on the SoC you can load key positions without actually knowing the value inside. You also don't see the microcode of the crypto-processor, ever, because then even at the time of manufacture you can't inject anything.

If you have keys or certs that won't fit into the generous chip registers then you have to store them in RAM and/or NVM, but because of the crypto-processor you don't need to expose those values. The RAM or NVM itself can be scrambled by the chip with a key which is not known by anyone but itself.

Lastly unlike in computers, secure embedded systems also have some physical security. RAM connection tracks aren't permitted to be on the surface of the PCB ("buried vias"). This is because if there are elements which are in the clear in RAM then you need to limit access, it is possible to slow down or freeze the CPU and then probe the RAM.

Finally for smart cards it has been possible to intercept the transactions between the SoC and the card. This is called "Card sharing", the solution to this is to encrypt the transactions between the card and the SoC and bind them to each other so they can't be swapped or shared.

I know that DRM/content security is unpopular with some people on the interwebs, but I thought I would share some high-level concepts from an industry which has some particular security requirements.

*In theory.

3
  • 3
    +1. Do you know if there's been any efforts to do anything like this in modern laptop/desktop computers? I bet at least a few industries (think military, government) would be interested in having access to this level of security. Or this would have to be a totally customized electronic appliance?
    – mjuarez
    Commented Aug 2, 2014 at 21:58
  • 4
    In theory the more recent changes to EFI boot which are used by Microsoft can be used by Linux to build the chain of trust and as @mricon says elsewhere SElinux helps. I have also been looking at OKL4 for high security because you can take secure components outside of Linux to another OS.
    – bob_dvb
    Commented Aug 10, 2014 at 10:14
  • 1
    @mjuarez, possibly of interest: decapping TPM chips. Commented Apr 6, 2018 at 0:38
29

There is some work being done on the Linux platform to disallow accessing memory of a running process, even by a superuser. With SELinux, you can do it starting with Fedora 17: SELinux Deny Ptrace.

0
18

What language/platform are you using?

If it's .NET, check out the PasswordBox control and the SecureString class.

The SecureString class represents a way to store the password in memory without making it accessible to anyone - even hackers who sneak peeks at your application's memory.

The PasswordBox control is a textbox that incorporates the SecureString, so you can keep the password safe and secure from end-to-end.

6
  • 6
    please dont just post links as your answer. try your best to elaborate your answer and only then post links as source/credits. if the links are gone, so is your answer. Commented Jan 14, 2013 at 19:35
  • 4
    @Lorenzo +1 I agree. I have a habit of posting my answers in a series of edits rather then getting it all out in one go. Although I'm not worried about MSDN links dying anytime soon. :)
    – Giffyguy
    Commented Jan 14, 2013 at 19:38
  • 10
    @Giffyguy - It makes sense to use a SecureString in .NET for several reasons, but it doesn't prevent sophisticated "hackers who sneak peeks at your applications memory" from getting at the password; it adds obfuscation though. SecureStrings will be encrypted in memory; however the key to decrypt will necessarily also be in memory. Still this is better than a plaintext pw in memory, so it isn't ever exposed in a coredump/swapfile/etc.
    – dr jimbob
    Commented Jan 14, 2013 at 20:29
  • 8
    What SecureString gains is pretty limited. It's against crashdumps and swapfiles. It doesn't protect against malicious applications that can access your process memory. Those applications being able to get your password isn't a security breach, and MS won't patch it. Commented Jan 14, 2013 at 21:08
  • 5
    @CodesInChaos - Exactly. SecureString uses the Data Protection API; which was reverse engineered in 2010 (not sure if MS has changed since then). Its not trivial to break (e.g., if you had full access to a system; its much easier to just capture the password before it hit the SecureString with say a keylogger). However, since the running application has to be able to decrypt it; a sophisticated analysis (with full access to disk/memory) has to be able to recover it.
    – dr jimbob
    Commented Jan 14, 2013 at 22:08
16

No, passwords stored in plaintext in RAM shouldn't be considered as safe. Generally, on the x86 and x86-64 architectures with interfaces such as FireWire, ExpressCard and Thunderbolt which directly access, these interfaces can be used to bypass operating system memory protection, and thus get plaintext passwords from memory.

Using FireWire to gain plaintext passwords isn't simply a theoretical attack. Software is now being sold to get plaintext passwords for BitLocker, PGP and TrueCrypt encrypted disks ElcomSoft Decrypts BitLocker, PGP and TrueCrypt Containers

There's a separate thread on security.stackexchange that touches on how to mitigate DMA base attacks Safely disable firewire/thunderbolt, patching up DMA exposure under Linux. Also Microsoft have a knowledge base article to mitigate attacks via Firewire and Thunderbolt on BitLocker Blocking the SBP-2 driver and Thunderbolt controllers to reduce 1394 DMA and Thunderbolt DMA threats to BitLocker

More details on this attack can be found on Wikipedia DMA attack.

7

In addition to all the software attacks exploiting OS vulnerabilities if an attacker has physical access to your machine they can potentially read your keys directly out of your memory.

How can the impact of cold boot attacks be minimized?

2
  • 5
    "If an attacker has physical access to your machine" then pretty much all bets are generally considered to be off, and the attacker's ability to read a password out of a variable in memory is usually the least of your problems.
    – user
    Commented Jan 14, 2013 at 22:20
  • 1
    A possible protection against cold boot attacks is cryptography which encrypts the contents of the RAM and only uses the CPU registers as "trusted" locations to store the encryption keys. Check out e.g. <en.wikipedia.org/wiki/TRESOR>.
    – a3nm
    Commented Mar 18, 2013 at 9:35
7

You raise a valid issue and indeed this is often addressed in security-related software. When sensitive objects such as keys are no longer needed, some programs will not simply hand the memory back to the memory management library or operating system, but first obliterate the sensitive bits by overwriting them.

Of course, some programs need to hold keys persistently. For example ssh-agent. So these programs are vulnerable. If you're a plain user on a multi-user machine, your ssh-agent's dynamic memory is vulnerable to anyone who has root privs and can see any part of the machine's memory.

And anyway, even programs that use keys briefly still have a window of vulnerability. A microsecond can be an eternity in CPU time. A malicious superuser could even pause the program indefinitely on some instruction, while that program has sensitive data in plain-text form somewhere in memory.

So, as a rule of thumb, do not perform any security-sensitive computing on machine if that machine has any users or software you do not trust, and an operating system that you do not trust to prevent those users or software from escalating their privilege such that they can peek at your keys or plaintext data.

When using any secure client, you're trusting that program, and the entire platform it runs on down to the hardware and every machine instruction in every program that came preinstalled or that you installed afterward.

(The so-called "trusted computing" does not fix this; it just changes who the villains are.)

2
  • 3
    +1 The so-called "trusted computing" does not fix this; it just changes who the villains are Commented Jan 15, 2013 at 15:52
  • Since this is true, how is all the software-based drm implemented? (playready < 3.0, widevine, primetime, etc.)
    – davidkomer
    Commented Jun 16, 2016 at 6:02
5

Even if the keys are encrypted, cod boot attack can retrieve your password: Check this video of the cold boot attack underway.. http://www.youtube.com/watch?v=JDaicPIgn9U

2

There is a certain amount of trust that will always have to exist with the security of the OS and applications running, unless of course you have the time to read all the source code and verify no exploits exist. If you had that time, no trust is necessary, you'd know. But that's not probable. If it all possible, it's best to run proprietary projects on one machine and keep anything that must be trusted running on an another machine. The physical separation does the trick pretty well vs. faith based solutions.

4
  • 1
    You're absolutely right. That's also why I (or at least try to) only run free software my computer. Commented Jan 18, 2013 at 14:59
  • Could you elaborate on why there has to be any amount of trust between the OS and an application? I thought that with sufficient sandboxing (root jail, limited permissions, etc.) it should be, in theory, possible to run a virus safely. I'm not suggesting it's practical or 100% safe, but it should be possible to entirely sandbox an untrusted application.
    – Luc
    Commented Mar 18, 2013 at 10:30
  • @Luc sure, but this is not at all about sandboxing. you don't run your daily tasks in a sandbox, do you?
    – Kaii
    Commented Jan 15, 2014 at 20:59
  • @Kaii If I had some sort of important job, it might be an option.
    – Luc
    Commented Jan 16, 2014 at 10:20
2

A somewhat relevant study is what needs to be done to make sure that even the superuser can not access a secret that is stored in the memory of some other process. I never really finished the endeavour, so it is only a starting point. And this does nothing to prevent any physical attacks such as cold boot attacks.

Keeping secrets from root on Linux

1

This does not solve your problem, though one trick you can use to minimize the time a password or another secret is stored in memory is to it zero out afterwards.

Beware to use a method that guarantees you are writing to the same memory instead of allocating a new object with a different value. For example, in Java you would use a byte[] instead of a String to hold a secret.

1
  • I was reading this and thinking something similar. If you need to store it in RAM, can't the password be encrypted during that time? I know it has to exist at some point in plain text, but that can be minimized.
    – Bratch
    Commented Jan 15, 2014 at 20:08
1

Given that this could apply to a number of OSes with varying protection levels, a few things to keep in mind:

  1. No matter what, you cannot stop a password from being in memory at some point. If someone has live access to the memory of your application, you cannot stop them from seeing it.

  2. Passwords are generally more valuable than just what they protect - users reuse passwords, and by accepting password login you are taking on some level of responsibility for keeping their password secret, even if the data it protects is compromised. You can somewhat mitigate the damage of an attack on cold memory (liquid nitrogen or hibernate) by hashing your users password with a slow hash function (PBKDF, scrypt, bcrypt) and using the hash for authentication.

  3. Clearing your users password from memory is good practice. There are many pitfalls involved in doing this properly, so make sure to use an appropriate library: Windows Linux Example

1

Passwords aren't normally stored in memory. Password hashes, or encrypted passwords, are stored in memory and used.

When creating the hash or encryption the password is in memory. So then you use something like "ZeroMemory" or SecureZeroMemory / RtlSecureZeroMemory. And you store only the encrypted value.

Problems exist with cross-platform programs that don't do password sanitation correctly, or that use unencrypted passwords for inter-process communication, but that's just a fail. Recovery of passwords from memory has been frequently demonstrated.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .