Thursday, October 02, 2014

Passwords In Your Bash History

This is one of those things that is utterly annoying because you can only get mad at yourself.  At work, I have my ssh key populated on a lot of our systems, but there are also plenty of systems where it is not residing as of yet.  When I really get working on something, and working in a quicker than usual manner, there will be times I ssh to a system and don't realize that it "just connected".  The problem is that my fingers are acting way ahead of what I am seeing and have already typed my password and hit enter. 

Well, the problem is that your going to get an error because you password is not typically a command.  Its at that point that you will realize that you messed up and that password is now residing in your bash history. 

Initial searches will show that you can simply edit your history file and remove the offending line(s).  Sure, but I don't want to have to go through all that if I don't have to.  So, digging further you will find that you can simply do this (assuming that you did not type anything else after typing your password and hitting enter):

    history -d $((HISTCMD-1))

This works because the above command adds a line to the history file and you want the previous entry, which is your beloved password.  It will promptly remove it from the history, saving you the worry of having it in there.  The HISTCMD returns the latest command number in the history (reflecting the command you are entering currently to display it).

Now, if you continued typing in commands and figured you would get back to removing it, there is another way you can do this.  First, type 'history' and hit enter.   If your like me, you have your history sett to be thousands of lines, so you may want to pipe it through less or more to halt the scrolling off of your screen, like so:

    history | less

The output will look similar to the following (just more lines):

    757  ls
    758  ls -lart
    759  cat .bashrc
    760  exit
    761  clear

The line number is to the left and the command that was entered is on the right.

Find the line number with your password and issue the following:

    history -d

replacing with the offending number from the history output.

Another example is, say you want to remove all occurrences of a command from your history (and this could work for your password as well).  Simply run the following:

    history | grep "clear" | awk '{print $1}'

That will output the line numbers in your history.  You then just type them each into a 'history -d' to remove them.  Yes, that's tedious, but that is where shell scripting comes in really handy.  Write a script to do it for you.  For instance the shell script could:

- take a single word command as input (to search for)
- find all occurrences of that command in the history and save the line numbers (to an array)
- cycle over the array and run each number through a 'history -d', removing it.

There are a bunch of possibilities.  Of course, you can also add a bit of configuration to your history, reducing occurrences.  In your .bashrc, you can set the HISTCONTROL variable with options that tell the history how to act. 

In my .bashrc you will find the line:

    export HISTCONTROL=ignoredups:ignorespace

What that does is tell history to not record a command that is already in the history, and to ignore a leading space.  That last one is VERY useful when you want to do something but not have any record of it in your history.  You simply hit a space before typing your command and that command will not end up in your history.

Hopefully this helps someone out there keep their passwords secret and not in their history file. 


Karl Puder said...

And if you change all your passwords to add a space as the first character, the ignorespace option will keep your accidental typeahead from getting into your history at all.

Numberwhun said...

Thanks, Karl! I was so into writing the article I didn't think of that.

Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 License.