43

Recently, I have been looking for the possibility to pass sensitive information from one process to another (at process startup time) without passing it through the command line or without using a filesystem entry. This is on Linux but the question applies to other systems, too.

In particular, the password to access a MySQL server shall be passed down from a script to the MySQL client. To do so, you can pass it over the command line (-pPASSWORD), but this is nasty as a simple process listing will then reveal the password to all other users. In this precise case, the MySQL client program is friendly enough to overwrite the command line text, replacing the visible password string by XXX but this is a smelly solution.

I thought about use the process environment instead. The script sets the password in the process environment, the started subprocess can then read it from there. Indeed, the MySQL client allows this and looks for the environment variable MYSQL_PWD. This looks pretty secure and also elegant, as a process environment cannot be consulted by anyone but root and the process owner, at least as far as I know.

However, the MySQL 5.1 manual states:

This method of specifying your MySQL password [via the environment] must be considered extremely insecure and should not be used. Some versions of ps include an option to display the environment of running processes. On some systems, if you set MYSQL_PWD, your password is exposed to any other user who runs ps. Even on systems without such a version of ps, it is unwise to assume that there are no other methods by which users can examine process environments."

The question then is: Is passing sensitive data through the process environment really insecure? Are there systems that allow consultation of another process' environment with no verification of permissions? Clearly, the superuser can grab the password at will, but then again, he doesn't need it in the first place.

David Tonhofer
  • 781
  • 6
  • 13
  • 1
    Yeah another process running the same user can access environment of another process, and if you keep there a password, it might leak, but the same way you would get password from a local file system, because this process has simply access to this file. So if it's config file, or the environment file, this doesn't make difference if this is passed only to the mysql client process. – Andrew Smith Jul 22 '12 at 21:01
  • 3
    For Linux specifically, see [environment variable accessibility in Linux](http://security.stackexchange.com/q/14000). – Gilles 'SO- stop being evil' Sep 18 '12 at 09:00
  • Another "rumor has it" line found in man page of openssl 1.0.2k-8.el7: *"Several commands accept password arguments... [using] env:var [means] obtain the password from the environment variable var. Since the environment of other processes is visible on certain platforms (e.g. ps under certain Unix OSes) this option should be used with caution."* – David Tonhofer Jan 09 '18 at 18:33

4 Answers4

25

To answer my own question:

It seems that some systems are, or rather were indeed insecure, leaking environment information to other processes.

A similar issue to the present one is raised on github by user 'mitchblank' for the 'mosh' application (mobile shell). The author writes:

Background: in the process image argv[] and envp[] are stored in the same way, next to each other. In "classic" UNIXes /usr/bin/ps was typically setgid "kmem" (or similar group), which allowed it to dig around in /dev/kmem to read information about the active processes. This included the ability to read the process arguments AND the environment, of all users on the system.

These days these 'privileged ps hacks' are largely behind us: UNIX systems have all come up with different ways of querying such information (/proc on Linux, etc) I think all(?) of these consider a process's environment only to be readable by its uid. Thus, security-sensitive data like passwords in the environment aren't leaked. However, the old ways aren't 100% dead. Just as an example, here's an example from an AIX 5.2 machine I have access to...."

....

Today, mosh seems to be only on Linux/OSX/FreeBSD but if it catches on I'm afraid it will end up on some platform that still uses the old-school UNIX "everybody can see anybody's environment variables" model.

I have been unable to confirm the existence of any system that permitted the leaking of environment variables (A work for historians and people having access to old installations.)

Looking around shows that in 2000, environment variables were indeed considered sensitive, i.e. potential problems would have been flagged, see CERT vulnerability 22404. Indeed the above-mentioned mentioned AIX 5.2 weakness was a bug (Since fixed. Unfortunately there is no detailed information about this on the Internet as far as I can find apart from this IBM technical bulletin)

CERT and RISKS forum yield nothing about environment variables being implemented in an insecure manner or being exploited at any point in time.

I am not sure whether other programs pass sensitive data around (GPG does not), but the MySQL manual's admonishment seems to be over the top.

David Tonhofer
  • 781
  • 6
  • 13
6
user@example(pts/1)$ cd /proc/1022 
user@example(pts/1)$ ls -lha environ 
-r-------- 1 root root 0 Jul 22 17:20 environ

So, on Linux it is secure. It may not be secure on other UNIX-like OSs...

Unless you can't trust root, but then all bets are off.

Hubert Kario
  • 3,708
  • 3
  • 27
  • 34
4

The old conventional wisdom used to be: No, the environment is not secure. Do not pass secrets through the environment.

I don't know whether the old conventional wisdom is still applicable. At least on the latest versions of Linux, it no longer seems to be possible for one process to view another process's environment (if they are owned by different users). However, I don't know what other operating systems do. I would be pretty leary about passing secrets through the environment; it doesn't sound like the sort of thing that I'm confident all operating systems will protect.

A safer solution: set up a pipe (if the two processes have some sort of child-parent relationship), or use inter-process communication (IPC), or store it in a private file that no one else can read. The best solution will probably depend upon your circumstances. If you are writing application code, you might consider one of the first two mechanisms. If you are writing a shell script, the simplest is probably to store it in a private file whose permissions are set to make sure no one else can read it. At least that's what I'd do -- though it's always possible I'm being overly conservative.

Of course, if you are writing a script that only needs to work on a single system, then you can test that system to see if anyone else can view the environment. But if you are writing general code for widespread use, I would lean towards the solutions in the previous paragraph instead of passing secrets through the environment -- though I admit I can't point to any modern system where using the environment would indeed be unsafe.

D.W.
  • 98,420
  • 30
  • 267
  • 572
0

Imagine that you are running a web/application server which given the DB password through an environment variable (you do that to avoid having the password stored on the disk for ex.). If your server/website has an unknown vulnerability (ex: path traversal…) that allows an attacker to read arbitrary files, it may be able to read /prod/[THE_PID]/environ. If you are running your server in a Docker container, it may be easy for the attacker to guess the PID of your process server (possibly 1). In this case, passing the password through the standard input looks safer (if you can).

fskexp
  • 1