나는 (1) 사용자가 bash 쉘 프롬프트에 비밀번호를 입력하고 해당 비밀번호가 프로그램의 표준 입력의 일부가 되도록 하는 가장 안전하고 (2) 가장 쉬운 방법을 찾고 있습니다.
이것이 stdin의 모습입니다: {"username":"myname","password":"<my-password>"}
, <my-password>
쉘 프롬프트에 입력된 내용은 어디에 있습니까? 프로그램의 표준 입력을 제어할 수 있다면 비밀번호를 안전하게 입력하고 제자리에 두도록 수정할 수 있지만 다운스트림은 표준 범용 명령입니다.
나는 다음을 사용하는 접근 방식을 고려하고 거부했습니다.
- 사용자는 명령줄에 비밀번호를 입력합니다. 비밀번호는 화면에 표시되며 "ps"를 통해 모든 사용자에게 표시됩니다.
- 쉘 변수는 외부 프로그램의 매개변수(예
...$PASSWORD...
: )에 삽입됩니다. 비밀번호는 여전히 "ps"를 통해 모든 사용자에게 표시됩니다. - 환경 변수(환경에 남아 있는 경우): 암호는 모든 하위 프로세스에 표시됩니다. 신뢰할 수 있는 프로세스라도 진단 중에 핵심을 덤프하거나 환경 변수를 덤프하면 암호가 노출될 수 있습니다.
- 비밀번호는 엄격한 권한이 있는 파일에도 오랫동안 파일에 저장됩니다. 사용자는 실수로 비밀번호를 노출할 수 있으며 루트는 실수로 비밀번호를 볼 수 있습니다.
현재 솔루션을 아래 답변으로 남겨두겠습니다. 하지만 누군가가 더 나은 답변을 제안하면 기꺼이 더 나은 답변을 선택하겠습니다. 더 간단한 것이 있어야 한다고 생각합니다. 아니면 누군가 제가 놓친 보안 문제를 발견했을 수도 있습니다.
답변1
또는 :bash
zsh
unset -v password # make sure it's not exported
set +o allexport # make sure variables are not automatically exported
IFS= read -rs password < /dev/tty &&
printf '{"username":"myname","password":"%s"}\n' "$password" | cmd
그렇지 않은 경우 IFS=
입력 read
한 비밀번호에서 앞뒤 공백이 제거됩니다.
그렇지 않은 경우 -r
백슬래시를 따옴표 문자로 처리합니다.
터미널에서만 데이터를 읽을 수 있는지 확인하려고 합니다.
echo
안정적으로 사용할 수 없습니다. bash
및 에는 가 zsh
내장 printf
되어 있으므로 의 출력에 명령줄이 표시되지 않습니다 ps
.
당신 은 bash
인용해야합니다 $password
. 그렇지 않으면분할+전역연산자가 적용됩니다.
하지만 해당 문자열을 JSON으로 인코딩해야 하기 때문에 이는 여전히 잘못된 것입니다. 예를 들어, 큰따옴표와 백슬래시는 적어도 문제입니다. 이러한 문자의 인코딩에 대해 걱정해야 할 수도 있습니다. 프로그램에 UTF-8 문자열이 필요합니까? 당신의 단말기는 무엇을 보내고 있나요?
프롬프트 문자열을 추가하려면 다음을 사용하십시오 zsh
.
IFS= read -rs 'password?Please enter a password: '
그리고 bash
:
IFS= read -rsp 'Please enter a password: ' password
답변2
내 솔루션은 다음과 같습니다(테스트됨).
$ read -s PASSWORD
<user types password>
$ echo -n $PASSWORD | perl -e '$_=<>; print "{\"username\":\"myname\",\"password\":\"$_\"}"'
설명하다:
read -s
화면에 줄을 표시하지 않고 표준 입력(암호) 줄을 읽습니다. 이는 쉘 변수 PASSWORD에 저장됩니다.echo -n $PASSWORD
개행 없이 표준 출력에 비밀번호를 입력하십시오. (echo는 쉘에 내장되어 있으므로 새 프로세스가 생성되지 않으므로 (AFAIK) echo 인수인 비밀번호가 ps에 표시되지 않습니다.)- Perl이 호출되어 stdin에서 비밀번호를 읽습니다.
$_
- Perl은 비밀번호를
$_
전체 텍스트로 입력하고 표준 출력으로 인쇄합니다.
이것이 HTTPS POST인 경우 두 번째 줄은 다음과 같습니다.
echo -n $PASSWORD | perl -e '$_=<>; print "{\"username\":\"myname\",\"password\":\"$_\"}"' | curl -H "Content-Type: application/json" -d@- -X POST <url-to-post-to>
답변3
read
귀하의 버전이 이를 지원하지 않는 경우 -s
POSIX 호환성을 사용해 보십시오 .이 답변.
echo -n "USERNAME: "; read uname
echo -n "PASSWORD: "; set +a; stty -echo; read passwd; command <<<"$passwd"; set -a; stty echo; echo
passwd= # get rid of passwd possibly only necessary if running outside of a script
set +a
변수가 자동으로 환경으로 "내보내지는" 것을 방지 해야 합니다 . 매뉴얼 페이지를 확인해야 합니다 stty
. 사용 가능한 옵션이 많이 있습니다. <<<"$passwd"
좋은 비밀번호에는 공백이 있을 수 있으므로 인용했습니다 . echo
활성화 후 마지막 단계는 stty echo
다음 명령/출력이 새 줄에서 시작되도록 하는 것입니다.