Ask for a password in POSIX-compliant shell?

When I want to ask for a password in a bash script, I do that :

read -s

…but when I run bash in POSIX mode, with sh, the -s option is rejected:

$ read -s
sh: 1: read: Illegal option -s

How do I securely ask for an input with a POSIX-compliant command ?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

read_password() {
  REPLY="$(
    # always read from the tty even when redirected:
    exec < /dev/tty || exit # || exit only needed for bash

    # save current tty settings:
    tty_settings=$(stty -g) || exit

    # schedule restore of the settings on exit of that subshell
    # or on receiving SIGINT or SIGTERM:
    trap 'stty "$tty_settings"' EXIT INT TERM

    # disable terminal local echo
    stty -echo || exit

    # prompt on tty
    printf "Password: " > /dev/tty

    # read password as one line, record exit status
    IFS= read -r password; ret=$?

    # display a newline to visually acknowledge the entered password
    echo > /dev/tty

    # return the password for $REPLY
    printf '%sn' "$password"
    exit "$ret"
  )"
}

Note that for those shells (ksh88, mksh and most other pdksh-derived shells) where printf is not builtin, the password would appear in clear in the ps output (for a few microseconds) or may show up in some audit logs if all command invocations with their parameters are audited. In those shells however, you can replace it with print -r -- "$password".

In any case echo is generally not an option.

Another POSIX-compliant one that doesn’t involve revealing the password in the ps output (but might end up having it written onto permanent storage) is:

cat << EOF
$password
EOF

Also note that zsh’s IFS= read -rs 'pass?Password: ' or bash’s IFS= read -rsp 'Password: ' pass issue the Password: prompt on stderr. So with those, you might want to add a 2> /dev/tty to make sure the prompt goes to the controlling terminal.

In any case, make sure you don’t forget the IFS= and -r.

Method 2

read -s is not in POSIX. If you want to be POSIX-compliant use the stty -echo. stty and its echo parameter are defined in POSIX.

#!/bin/bash
stty -echo
printf "Password: "
read PASSWORD
stty echo
printf "n"

This will work on all shells that conform to POSIX.

Source


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x