Estou procurando a (1) maneira mais segura e (2) mais simples de fazer com que um usuário digite uma senha em um prompt do shell bash e fazer com que essa senha se torne parte do stdin em um programa.
É assim que o stdin precisa se parecer:, {"username":"myname","password":"<my-password>"}
onde <my-password>
está o que foi digitado no prompt do shell. Se eu tivesse controle sobre o programa stdin, poderia modificá-lo para solicitar com segurança uma senha e colocá-la no lugar, mas o downstream é um comando padrão de uso geral.
Eu considerei e rejeitei abordagens que usam o seguinte:
- o usuário digitando a senha na linha de comando: a senha seria mostrada na tela e também visível a todos os usuários via "ps"
- interpolação de variável de shell em um argumento para um programa externo (por exemplo,
...$PASSWORD...
): a senha ainda estaria visível a todos os usuários via "ps" - variáveis de ambiente (se forem deixadas no ambiente): a senha seria visível para todos os processos filhos; mesmo processos confiáveis podem expor a senha se despejarem variáveis de ambiente principais ou de despejo como parte de um diagnóstico
- a senha em um arquivo por um longo período de tempo, mesmo um arquivo com permissões restritas: o usuário pode expor acidentalmente a senha e o usuário root pode vê-la acidentalmente
Colocarei minha solução atual como resposta abaixo, mas selecionarei com satisfação uma resposta melhor se alguém tiver uma. Eu estou pensando que deveria haver algo mais simples ou talvez alguém veja uma preocupação de segurança que eu perdi.
Respostas:
Com
bash
ouzsh
:Sem
IFS=
,read
removeria espaços em branco à esquerda e à esquerda da senha digitada.Sem
-r
, ele processaria barras invertidas como um caractere de citação.Você quer ter certeza de ler apenas a partir do terminal.
echo
não pode ser usado com segurança. Embash
ezsh
,printf
está embutido para que a linha de comando não apareça na saída deps
.Em
bash
, é necessário citar$password
, caso contrário, o operador split + glob será aplicado a ele.Ainda está errado, pois você precisará codificar essa sequência como JSON. Por exemplo, aspas duplas e barra invertida pelo menos seria um problema. Você provavelmente precisa se preocupar com a codificação desses caracteres. Seu programa espera cadeias UTF-8? O que o seu terminal envia?
Para adicionar uma string de prompt, com
zsh
:Com
bash
:fonte
unset password
eset +a
lá, embora possa ser ignorado se você puder fazer mais suposições sobre o shell atual. Bom argumento sobre a opção -r para ler e colocarIFS=
à frente para uma melhor generalidade com uma variedade de senhas. É bom ir de / dev / tty para forçar a entrada do terminal.python3 -c 'import json; print(json.dumps({"username": "myname", "password": input()}))'
, se você tiver Python por aí. Para Python 2, s / input / raw_input /. Se você canalizar a senha nesse comando, ele emitirá o JSON apropriado.Aqui está a solução que tenho (foi testada):
Explicação:
read -s
lê uma linha de stdin (a senha) sem ecoar a linha na tela. Ele armazena está na variável do shell PASSWORD.echo -n $PASSWORD
coloca a senha em stdout sem nenhuma nova linha. (echo é um comando interno do shell, portanto, nenhum novo processo é criado, portanto (AFAIK) a senha como argumento para eco não será mostrada no ps.)$_
$_
texto completo e a imprime em stdoutSe isso for para um HTTPS POST, a segunda linha seria algo como:
fonte
printf '{"username":"myname","password":"%s"}' $PASSWORD
, que mantém as mesmas propriedades de segurança e economiza um processo externo.read
comandos que não suportam o sinalizador -s, pode usar "stty -echo; leia PASSWORD; stty echo"perl -e '...' <<< "$PASSWORD"
.<<<
embash
lojas o conteúdo em um arquivo temporário que é pior.Se sua versão do
read
não suportar,-s
tente a maneira compatível com POSIX vista nesta resposta .O
set +a
é suposto para evitar auto "exportação" de uma variável para o meio ambiente. Você deve verificar as páginas de manualstty
, pois há muitas opções disponíveis. O<<<"$passwd"
é citado porque boas senhas podem ter espaços. O últimoecho
após ativar ostty echo
é ter o próximo comando / saída iniciado em uma nova linha.fonte