xtpu has asked for the wisdom of the Perl Monks concerning the following question:

Greetings, monks!

I come to you with some security related questions. I'm coding a daemon that needs to periodically access encrypted data and perform operations on it. At the same time, I need to prevent access from the data in case someone manages to log into the machine. I was figuring doing something likes this:

Upon launch, the daemon asks for the decryption password, which is assigns to a variable and retains all through its run-time. It can then use the password to access the encrypted data, get the information it needs and perform operations.

My first question is: is it possible for someone with terminal access to the system (it is a Linux system) to access the values of variables within a perl script from the outside? Perhaps if they did a memory dump? "hexdump -c"?

My second question is: How about the input stream for a script? I was planning to enter the password simply via <STDIN>. Can someone read things from STDIN from before they accessed the stream?

I apologize in advance. These questions are probably really stupid and show my ignorance of even the simplest things about Perl and Linux. Unfortunately, I had no formal schooling in this kind of stuff so my ignorance is vast. I would appreciate any pointers, because I don't know where to even start looking.

  • Comment on Reading streams, perl variables when script is running

Replies are listed 'Best First'.
Re: Reading streams, perl variables when script is running
by dave_the_m (Monsignor) on Jan 04, 2014 at 10:52 UTC
    On a UNIX/Linux system, anyone who is logged in as root or as the same user that the daemon is running as, can have complete access to the memory of the daemon and can thus (in principle) read the value of any variable. This could be done crudely with hexdump or strings and grep, or more sophisticatedly, by running gdb against the perl process.

    Also they can (using strace for example) see all the data that is read from STDIN or any other file handle.

    I don't know about Windows, but I would expect similar caveats to apply.

    Dave.

      On Windows, it is quite similar, except that there is a separate privilege your user account needs, "Debug Privilege", to attach a debugger to a process not owned by you. As the article says, you can debug your own processes without that.

        Modern Linux also uses such privileges, called capabilities. CAP_SYS_PTRACE lets you trace arbitrary processes. It is also possible to give capabilities to an executable.
Re: Reading streams, perl variables when script is running
by Preceptor (Deacon) on Jan 04, 2014 at 11:59 UTC

    A privileged user or the owner of the process can do whatever they wish with it. There's a load of options, and basically nothing you can to to 'protect' it. However running the 'password/decrypt' as a different userid means at least it'd require root to interfere, which is about as good as you're going to get.

    Same applies to injection and interfering with STDIN - root can, other users can't. (At least assuming you're not doing something particularly daft with your code).

Re: Reading streams, perl variables when script is running
by kcott (Archbishop) on Jan 04, 2014 at 11:00 UTC

    G'day xtpu,

    Welcome to the monastery.

    There are a number of FAQs (in perlfaq8 and perlfaq9) with information about passwords. The most relevant to your question would be "How do I ask the user for a password?"; although, the others may be of interest.

    You can put lexical variables in an anonymous scope to make them private. In the following demo script, only the subroutines initialise_password() and retrieve_password() have access to the $password variable: even if you accidentally used $password somewhere else in your code, it would be a completely different variable.

    The following code shows the techniques you might use to read the password once at startup, store it in a private variable and retrieve it as many times as you want.

    #!/usr/bin/env perl use strict; use warnings; { my $password; sub retrieve_password { return $password if defined $password; die 'Password not defined'; } sub initialise_password { return if defined $password; use Term::ReadKey; print 'Enter password: '; ReadMode('noecho'); $password = ReadLine(0); print "\n"; ReadMode('restore'); return; } } start(); test(); sub start { initialise_password(); } sub test { print 'Testing: ', retrieve_password(), "\n"; }

    Sample run:

    Enter password: Testing: some_password

    -- Ken

      Thanks for the informative responses, guys. You're the best!

      Would it be a pretty accurate summary to say: keeping the decryption password in memory would work, as long as no one managed to gain root access?

      Small follow-up question: If I wanted to avoid using Term::ReadKey, would the following code work for reading the password? Is Term::ReadKey in any way more secure? (I prefer to avoid installing additional modules where I can for the sake of portability, unless I absolutely need them.)

      print "Password: "; system('stty','-echo'); my $pw=<STDIN>; system('stty','echo'); chomp($pw);
        "Small follow-up question: If I wanted to avoid using Term::ReadKey, would the following code work for reading the password? Is Term::ReadKey in any way more secure? (I prefer to avoid installing additional modules where I can for the sake of portability, unless I absolutely need them.) ... stty code ..."

        This rather indicates that you didn't bother to read the "How do I ask the user for a password?" link which I provided: it discusses both stty and portability issues.

        The security aspect here involves hiding the password being typed from prying eyes. That's an absolute (either it's hidden or visible) — there's no sliding scale of effective camouflaging or obfuscation. Perhaps you had something else in mind with respect to Term::ReadKey's security.

        Many modules are written with the express purpose of improving portability: Term::ReadKey is one of these; File::Spec is another example. You'll also find lots of modules are written to be portable even if that's not their primary function. There may be many reasons why you choose not to install any particular module; however, you should reject the notion of using portability as a reason for not installing modules in general.

        -- Ken

Re: Reading streams, perl variables when script is running
by grondilu (Friar) on Jan 04, 2014 at 10:43 UTC

    I'm ashamed to admit that I've often wondered the same things. It's not specific to Perl though, it's rather a question about security in Unix.

    I very much doubt it is possible to access the memory space of a program running under an other UID. Otherwise that would be an obvious security vulnerability. Same for standard input and output. Can you imagine if you could see the standard output of any terminal running on your machine, including other users's ones? That'd make Unix a joke in terms of security.