Estoy buscando la (1) forma más segura y (2) más simple de hacer que un usuario escriba una contraseña en un indicador de shell bash y que esa contraseña se convierta en parte de stdin para un programa.
Así es como debe verse el stdin:, {"username":"myname","password":"<my-password>"}dónde <my-password>es lo que se escribió en el indicador del shell. Si tuviera control sobre el programa stdin, entonces podría modificarlo para solicitar una contraseña de forma segura y ponerlo en su lugar, pero el downstream es un comando estándar de propósito general.
He considerado y rechazado enfoques que usan lo siguiente:
- el usuario escribiendo la contraseña en la línea de comando: la contraseña se mostrará en la pantalla y también será visible para todos los usuarios a través de "ps"
- interpolación variable de shell en un argumento a un programa externo (por ejemplo,
...$PASSWORD...): la contraseña aún sería visible para todos los usuarios a través de "ps" - variables de entorno (si se dejan en el entorno): la contraseña sería visible para todos los procesos secundarios; incluso los procesos confiables pueden exponer la contraseña si vuelcan las variables de entorno principales o de volcado como parte de un diagnóstico
- la contraseña se encuentra en un archivo durante un período prolongado de tiempo, incluso un archivo con permisos estrictos: el usuario puede exponer accidentalmente la contraseña y el usuario raíz puede ver la contraseña accidentalmente
Pondré mi solución actual como respuesta a continuación, pero con mucho gusto seleccionaré una mejor respuesta si a alguien se le ocurre una. Estoy pensando que debería haber algo más simple o tal vez alguien vea un problema de seguridad que me haya perdido.

Respuestas:
Con
bashozsh:Sin
IFS=,readeliminaría los espacios en blanco iniciales y finales de la contraseña que escriba.Sin
-r, procesaría barras invertidas como un carácter entre comillas.Debes asegurarte de que solo lees desde la terminal.
echono se puede usar de manera confiable. Inbashyzsh,printfestá integrado para que la línea de comando no se muestre en la salida deps.En
bash, debe citar$passwordya que de lo contrario se le aplicará el operador split + glob .Sin embargo, todavía está mal, ya que necesitarías codificar esa cadena como JSON. Por ejemplo, las comillas dobles y la barra diagonal inversa al menos serían un problema. Probablemente deba preocuparse por la codificación de esos caracteres. ¿Su programa espera cadenas UTF-8? ¿Qué envía tu terminal?
Para agregar una cadena de solicitud, con
zsh:Con
bash:fuente
unset passwordyset +aallí, aunque se puede omitir si puede hacer más suposiciones sobre el shell actual. Buen punto sobre la opción -r para leer y ponerIFS=por delante para una mejor generalidad con una variedad de contraseñas. Es bueno ir desde / dev / tty para forzar la entrada desde la terminal.python3 -c 'import json; print(json.dumps({"username": "myname", "password": input()}))', si tienes Python por ahí. Para Python 2, s / input / raw_input /. Si canaliza la contraseña en ese comando, escupirá el JSON apropiado.Aquí está la solución que tengo (ha sido probado):
Explicación:
read -slee una línea de stdin (la contraseña) sin hacer eco de la línea en la pantalla. Se almacena en la variable de shell CONTRASEÑA.echo -n $PASSWORDpone la contraseña en stdout sin ninguna nueva línea. (echo es un comando de shell incorporado, por lo que no se crea ningún proceso nuevo, por lo que (AFAIK) la contraseña como argumento para echo no se mostrará en ps).$_$_el texto completo y la imprime en stdoutSi esto va a una POST HTTPS, la segunda línea sería algo como:
fuente
printf '{"username":"myname","password":"%s"}' $PASSWORD, que conserva las mismas propiedades de seguridad y le ahorra un proceso externo.readcomandos que no admiten el indicador -s, puede usar "stty -echo; leer CONTRASEÑA; stty echo"perl -e '...' <<< "$PASSWORD".<<<enbashalmacena el contenido en un archivo temporal que es peor.Si su versión de
readno es compatible-s, pruebe la forma compatible POSIX que se ve en esta respuesta .Se
set +asupone que evita la "exportación" automática de una variable al entorno. Debería consultar las páginas de manual parastty, hay muchas opciones disponibles. Se<<<"$passwd"cita porque las buenas contraseñas pueden tener espacios. Lo últimoechodespués de habilitarstty echoes tener el siguiente comando / salida en una nueva línea.fuente