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
bash
ozsh
:Sin
IFS=
,read
eliminarí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.
echo
no se puede usar de manera confiable. Inbash
yzsh
,printf
está integrado para que la línea de comando no se muestre en la salida deps
.En
bash
, debe citar$password
ya 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 password
yset +a
allí, 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 -s
lee 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 $PASSWORD
pone 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.read
comandos que no admiten el indicador -s, puede usar "stty -echo; leer CONTRASEÑA; stty echo"perl -e '...' <<< "$PASSWORD"
.<<<
enbash
almacena el contenido en un archivo temporal que es peor.Si su versión de
read
no es compatible-s
, pruebe la forma compatible POSIX que se ve en esta respuesta .Se
set +a
supone 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 últimoecho
después de habilitarstty echo
es tener el siguiente comando / salida en una nueva línea.fuente