472

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.

Antoine Pinsard
  • 4,647
  • 4
  • 16
  • 27
  • 63
    This is actually the weakness of encryption. Any non encrypted value or waiting to be encrypted is stored in memory in plain text. – Lorenzo Von Matterhorn Jan 14 '13 at 19:33
  • 3
    You might find some useful background in [this question on Programmers](http://programmers.stackexchange.com/questions/181577). – Blrfl Jan 14 '13 at 21:03
  • 8
    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. Jan 14 '13 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 Jan 15 '13 at 00: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 Jan 15 '13 at 11:20
  • 1
    @OmarKohl That's what I did for my script. I first ask the password to unlock the keyring. Then I encrypt a random session password I send to the remote computer. And once I'm sure it received the new password I overwrite the password of the keyring. If it doesn't really solve the problem, it limits the time when the actual persistent password is stored in memory. – Antoine Pinsard Jan 15 '13 at 11:35
  • 1
    Related (as pointed out by someone on Hackernews): http://en.wikipedia.org/wiki/TRESOR – Luc Mar 18 '13 at 10:33
  • 1
    Doesn't HeartBleed give sections of memory to the attacker? – jkd Dec 05 '16 at 03:41
  • @jkd Yes, but only memory from the processes that linked against the vulnerable version of OpenSSL. Unfortunately, this often would include passwords, but only for that specific process. – forest Oct 19 '18 at 08:56

13 Answers13

492

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/Millenium 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.)

rkiyanchuk
  • 103
  • 3
Thomas Pornin
  • 322,884
  • 58
  • 787
  • 955
  • 40
    "virtual machines and cloud computing cannot be ultimately safe". I've always been skeptical about cloud computing. – Antoine Pinsard Jan 14 '13 at 22:07
  • 59
    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 Jan 14 '13 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](http://msdn.microsoft.com/en-us/library/system.security.securestring.aspx). However, this only mitigates the problem, doesn't solve it. – skolima Jan 15 '13 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). – Maciej Piechotka Jan 15 '13 at 11:10
  • I'm pretty sure I already knew all of this, but your powers of recall and ability to explain never fail to impress, thanks again Thomas. – lynks Jan 15 '13 at 11:35
  • Moreover, if you loose your computer, and it's still powered on, it is relatively easy to recover contents of RAM by freezing memory chips and reading the content: http://www.zdnet.com/blog/security/cryogenically-frozen-ram-bypasses-all-disk-encryption-methods/900 –  Jan 15 '13 at 18:28
  • kinda related, OpenGL is not required to clear the content of the framebuffer when creating buffers, so it is possible for a malicious program to grab what another program was drawing including those in non-visible buffers: http://stackoverflow.com/q/4112421/309412 – Lie Ryan Jan 17 '13 at 03:58
  • A good summary. Only additional point I'd mention is that while the OS attempts to provide adequate protection and services to support secure operations, others actively attempt to find holes. Add to this varying levels of understanding, care and ability amongst programmers and we can conclude, there are no guarantees. As usual, we need to evaluate based on the risk, likelihood and subsequent impact and then decide best/necessary actions. This article does a good job in providing the basics to assist in understanding the risk. The likelihood and impact will depend on the individual situation. – Tim X Jan 17 '13 at 22:16
  • This is an interesting answer. What I would add is that most security is a delusion - if some one targets you specifically then you are usually screwed and often without cracking encryptions or being especially clever - but good old fashioned dirty tricks like stealing someones password by watching them enter it. – jheriko Mar 18 '13 at 09:49
  • 3
    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. – Ethereal Mar 18 '13 at 15:19
  • 2
    What other model than the mainframe one is there? – Florian Margaine Jul 02 '13 at 12:01
  • Re: "The OS is your friend, because if the OS is an enemy then you have utterly lost," a nice account of *how* the OS can be turned against you and *what* it can do if that happens, see [Matthew Garrett's LibrePlanet 2013 talk](http://media.libreplanet.org/u/libby/m/embracing-secure-boot-and-rejecting-restricted-boot-matthew-garrett/) from about 7m15s. – sampablokuper Jan 01 '14 at 01:48
  • You've covered almost all the angles, but you did not mention that registers get saved on the stack all the time and when a context or thread switch happens all the registers get dumped to memory yet again. Ergo keeping secrets in registers is not save either. – Johan Feb 24 '16 at 02:18
  • @Johan That's correct, but the saved registers will not be swapped. – forest Oct 19 '18 at 04:08
59

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.

  • 2
    Thank you for this concise explanation for both Windows and GNU/Linux (I guess this values for other Unix systems as well). – Antoine Pinsard Jan 14 '13 at 20:54
  • 3
    @AntoinePinsard yes, if they implement `ptrace` it is highly likely! –  Jan 14 '13 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. – CodesInChaos Jan 14 '13 at 21:06
  • 4
    @Code true. I'm not sure any OS can defend you against yourself though! –  Jan 14 '13 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 Jan 14 '13 at 22:19
  • I would like to add that from searching around, it appears to be possible on linux to prevent being ptrace()'d and that software like ssh-agent (which I was worried about) protect against being ptrace()'d. See PR_SET_DUMPABLE [here](https://man7.org/linux/man-pages/man2/prctl.2.html) – MrFregg Jan 11 '22 at 20:59
42

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.

Matthew K.
  • 103
  • 3
bob_dvb
  • 521
  • 4
  • 4
  • 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 Aug 02 '14 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 Aug 10 '14 at 10:14
  • 1
    @mjuarez, possibly of interest: [decapping TPM chips](https://duckduckgo.com/html?q=decapping%20TPM%20chips). – sampablokuper Apr 06 '18 at 00:38
28

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.

mricon
  • 6,298
  • 23
  • 27
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.

Ozgur Ozcitak
  • 1,383
  • 2
  • 8
  • 5
Giffyguy
  • 281
  • 1
  • 4
  • 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. – Lorenzo Von Matterhorn Jan 14 '13 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. :) –  Jan 14 '13 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 Jan 14 '13 at 20:29
  • @dr jimbob +1 True, although hacking .NET is usually pretty futile. Any time there is a security breach, MS will usually release a patch within a few weeks or so to block it. – Giffyguy Jan 14 '13 at 20:34
  • 7
    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. – CodesInChaos Jan 14 '13 at 21:08
  • 5
    @CodesInChaos - Exactly. SecureString uses the [Data Protection API](http://en.wikipedia.org/wiki/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 Jan 14 '13 at 22:08
15

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.

petertonoli
  • 251
  • 2
  • 4
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?

  • 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 Jan 14 '13 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. . – a3nm Mar 18 '13 at 09: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.)

Kaz
  • 2,293
  • 16
  • 17
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.

cxx6xxc
  • 121
  • 2
  • 1
    You're absolutely right. That's also why I (or at least try to) only run free software my computer. – Antoine Pinsard Jan 18 '13 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 Mar 18 '13 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 Jan 15 '14 at 20:59
  • @Kaii If I had some sort of important job, it might be an option. – Luc Jan 16 '14 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

Nakedible
  • 4,531
  • 4
  • 26
  • 22
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.

gimix
  • 283
  • 2
  • 9
  • 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 Jan 15 '14 at 20:08
0

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