SecretPipe - A pipe in which to hide secrets


 use SecretPipe;
 $sp = new SecretPipe;
 $sp->hide("first secret");
 $sp->hide("second secret");
 $sp->hide("third secret");
 $x = $sp->reveal;  # will read back first secret
 $x = $sp->reveal;  # will read back second secret
 $sp->reset;        # will forget third secret


This is a poor implementation of a simple trick due to Bennet Yee ( The idea is to use the Kernel's buffer pool to hide a secret from prying eyes, since you have to be root to get at it. Of course, in this day and age of common remote root exploits, this doesn't seem as comforting as it once did, but it's still a reasonable short-term deterrent on a machine being used by more than one person that doesn't happen to be owned.

The basic idea is that you create a pipe, write a password on the write end of it, and then when you need it, read it back on the read end. Obviously, this trick only really works if you can guarantee that you've erased the password from memory in the interim, and only keep it around in plaintext as long as you have to, and even then if an attacker has the ability to make your process dump core and times it just right, they win. The pipe trick is really meant for long-running processes (like mail checkers) that need to use a password infrequently, but in a context in which it is inconvenient to have you type it. They squirrel the password away in the pipe (which is in the kernel's memory address space), and read it back when they need it.

As humble as this trick is, this implementaton is still shoddy, because there's no way in Perl to guarantee that the characters in the string you pass in get zapped. To do a proper job of this, I should rewrite it in XS and provide a primitive to zero the contents of a string for real.


  • new: construct a new SecretPipe. Takes no arguments.

  • finish: closes a SecretPipe's file descriptors and sets the counter of secrets it contains to zero.

  • hide: hides a new secret into the pipe.

  • reveal: read back the next secret from the pipe (in FIFO order).

  • reset: calls finish and then creates a new, empty pipe.


Sean Levy <>


  • perl(1).