Question

I sometimes mistakenly type my su password in a linux terminal that is echoing the typed characters. It gets recorded in ~/.bash_history which makes me feel insecure. Does anyone have a short script (bash one-liner?) to clean .bash_history of any plain text passwords?

Using sed leaves it's own traces in the .bash_history file, but if readline and/or history service could be temporarily disabled this might work:

sed -ir -e 's/su_password/PASSWORD_REMOVED/g' ~/.bash_history

And this could create additional problems/holes if the password is often used as part of other phrases/words.

Ideally, the script should just peruse the hashed passwd list (/etc/shadow) to create a list of search terms. Then it would have to hash portions of the file it's checking (.bash_history) for comparison. The problem is knowing how much of the text in the file to hash during the comparison as the length of the password is unknown. Alternatively, it could request the password in a secure way, like passwd does, before doing the grep/sed.

Was it helpful?

Solution

I usually do a echo > .bash_history to clear this. Although your password can show up in strange places so you might want to do a sudo grep "password" -R / first, to see if its anywhere else on the system, and then clear out your history.

OTHER TIPS

Not exactly just a one-liner, instead, a function:

eh () { history -a ; vi + ~/.bash_history ; history -r ; }

add this line to your .bashrc or .bash_profile. When run it

  1. saves the buffer to your .bash_history
  2. opens up .bash_history in vi, except with the pointer at the bottom of the file.
  3. restores the edited file to your current history buffer

While in vi, you can go up and down with the arrow keys, remove a line with dd and close and write the file with [Esc] :wq

now you just need to type eh at the command line and edit your history

eh stands for "edit history"

Since there weren't any answers that did the trick for me, I thought I'd share the script I'm currently using. It's certainly not a one-liner and not even bash ... but it works.

#!/usr/bin/env python
import os
user=os.getenv('USER')
if not user:
    user='hobs'
home=os.getenv('HOME')
if not home:
  home=os.path.normpath(os.path.join(os.path.sep+'home',user))
histfile=os.getenv('HISTFILE')
if not histfile:
    histfile=os.path.join(home,'.bash_history')
from optparse import OptionParser
p = OptionParser(usage="%prog [options] password", add_help_option=True)
p.add_option('-p', '--password', '--pass', '--pw', dest='pw',
             default =None,
             help="The plaintext password string you'd like to find and replace throughout your bash history file(s)", )
p.add_option('-r', '--replacement-password', '--replacement', '--filler', '--substitution', dest='rep',
             default ='',
             help="The replacement string, passphrase identifier, tag, or filler you'd like to leave behind wherever the password was found and removed.", )
p.add_option('-f', '--bash_history', '--historyfile', '--file', '--path', '--filename', dest='hfile',
             default =histfile,
             help="The text file where your password may have been accidentally recorded and where you'd like it removed. Default = ~/.bash_history.", )
(o, a) = p.parse_args()
if a and not o.pw:
    o.pw=' '.join(a) # password can have spaces in it
    print o.pw
    print len(o.pw)
# TODO: Check if the history buffer will record the invocation of this script that includes a plaintext password
#       Alternatively, launch the search/replace task in the background to start
#       after history has had a chance to record the last command in the history buffer
if o.pw:
    import warnings
    warnings.warn("Make sure you invoked "+p.get_prog_name()+" in such a way that history won't record this command (with a plaintext password) in the history file. It would be much  better if you didn't supply the password on the command line and instead allowed this script to securely prompt you for it.",RuntimeWarning)
if not o.pw:
    import getpass
    o.pw=getpass.getpass()
if len(o.pw)<4:
    raise ValueError(p.get_prog_name() + " doesn't accept passwords shorter than 4 characters long to prevent accidental corruption of files by purging common character combinations. The password you supplied is only "+str(len(o.pw))+" characters long.")
import fileinput
for line in fileinput.FileInput(o.hfile,inplace=1):
    line = line.replace(o.pw,o.rep)
    print line,
$ echo -n password=; stty -echo; sed -i "s/$(head -1)/PASSWORD_REMOVED/g" ~/.bash_history; stty echo
top-secret password that never appears anywhere else to make it easy to guess
$ #you have to type it in and press enter

The echo gives you the prompt. The stty helps protect against people looking over your shoulder. Make sure you escape anything (i.e. backslashes).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top