Oracle on Linux: How to hide your password when using a wrapper script

Sometimes, a DBA has to write an externally called wrapper script for various Oracle-supplied commands accepting password inputs. A prominent and simple example is SQL*plus (sqlplus).

The Problem

The process list shows all parameters of a command that’s currently executed.

wrapper1.sh

Accepts all connection infos on the command line:

#!/bin/bash
 cmdstring="sqlplus ${1}/${2}@${3}"
 echo "Executed command: $cmdstring"
 sleep 999

Called by:

$ ./wrapper1.sh system manager mydb
 Executed command: sqlplus system/manager@mydb

But now, the password is visible in the process list:

$ ps aux | grep wrapper1.sh | grep -v grep
 1000     20769  0.0  0.0  13808  1444 pts/1    S+   15:19   0:00 /bin/bash ./wrapper1.sh system manager mydb

 

Solution 1: Not Half Bad

Use here string syntax to get the password out of the process list cmd line.

wrapper2.sh

Uses READ to get input from stdin.

#!/bin/bash
 read -p "DB Password: " -s dbpassword
 echo
 cmdstring="sqlplus ${1}/${dbpassword}@${2}"
 echo "Executed command: $cmdstring"
 sleep 999
Called by:
 $ ./wrapper2.sh system mydb <<<'manager'
 Executed command: sqlplus system/manager@mydb

You can’t see the password in the process list any more, since the here string component is something your bash does for you:

$ ps aux | grep wrapper2.sh | grep -v grep
 1000     21509  0.0  0.0  13808  1452 pts/1    S+   15:25   0:00 /bin/bash ./wrapper2.sh system mydb

But here strings are represented as file descriptors, so the OS user and root still can see the password over its file handle.
The file itself was in /tmp, but is deleted for good reason. So you can’t find it there any more, but the handle is still open, and we cann see its content:

$ ls -l /proc/21509/fd/
 insgesamt 0
 lr-x------ 1 user user 64 Apr 30 15:31 0 -> /tmp/sh-thd-1398841958 (deleted)
 lrwx------ 1 user user 64 Apr 30 15:31 1 -> /dev/pts/1
 lrwx------ 1 user user 64 Apr 30 15:30 2 -> /dev/pts/1
 lr-x------ 1 user user 64 Apr 30 15:31 255 -> /home/user/test/wrapper2.sh
$ cat /proc/21509/fd/0
 manager

Solution 2: Better, but still not perfect

Use a pipe to get rid of the here string content in the file handle

wrapper3.sh

Again, we have READ to get data into the password variable, the only difference to wrapper2 is that this one has an additional sleep in the beginning to give us time for some dirty games. :)

#!/bin/bash
 echo "sleep 60"
 sleep 60
 echo "Sleep is over"
 read -p "DB Password: " -s dbpassword
 echo
 cmdstring="sqlplus ${1}/${dbpassword}@${2}"
 echo "Executed command: $cmdstring"
 sleep 999

Called by:

$ echo 'manager' | ./wrapper3.sh system mydb
  sleep 60
  Sleep is over
  Executed command: sqlplus system/@mydb

Again, we have no password in the process list. the ECHO is not in the process list, since I used the bash builtin ECHO, that’s not represented individually. Should you use /bin/echo, you’d have the password in the ps list again.

$ ps aux | grep wrapper3.sh | grep -v grep
 1000     25324  0.0  0.0  13808  1412 pts/1    S+   15:56   0:00 /bin/bash ./wrapper3.sh system mydb

And when we do nothing, the fd/0 file is empty, because the script read it:

$ cat /proc/25324/fd/0
$

But when we interfere earlier, we can “steal” the password out of the file descriptor:

$ echo 'manager' | ./wrapper3.sh system mydb
 sleep 60
$ ps aux | grep wrapper3.sh | grep -v grep
 1000     26750  0.0  0.0  13808  1412 pts/1    S+   16:09   0:00 /bin/bash ./wrapper3.sh system mydb

The password is “in the pipe” now, the script has not READ it yet. So we can suck it out:

$ cat /proc/26750/fd/0
 manager

Of course, the script can’t get the password now any more, usually the script will fail.

$ echo 'manager' | ./wrapper3.sh system mydb
 sleep 60
 Sleep is over
 Executed command: sqlplus system/@mydb

But the password now is in the hands of the guy executing the CAT command.

Summary

  • Easily avoid having your passwords on display in the process list, everybody with login rights on the server can read them!
  • Use here string syntax or even better, piping and the READ command to get the password into the script. Only root or the same OS user executing the script can read/steal the password now.



You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

2 Responses to “Oracle on Linux: How to hide your password when using a wrapper script”

  1. Mane Says:

    looks like this was inspired by “passwd –stdin” :-)

  2. TheBonsai Says:

    For a part of the spectrum, exec’ing sqlplus immediately after your preparation (wrapping) might also be okay.

    Like…

    #!/my/shell
    user=$1
    pass=$2
    logger “Logon to database as $user”
    exec sqlplus “$user/$pass”

Leave a Reply