bash - comando chpasswd
Forzar a cURL a obtener una contraseƱa del entorno (2)
Esta pregunta sobre el uso de cURL con un nombre de usuario y contraseña tiene respuestas subóptimas para mí:
-
curl -u "user:pw" https://example.com
pone el pw en la lista de procesos -
curl "https://user:[email protected]"
pone el pw en la lista de procesos -
curl -u "user:$(cat ~/.passwd)" https://example.com
pone el pw en la lista de procesos -
curl -u user https://example.com
solicita el pw -
curl --netrc-file ~/.netrc https://example.com
requiere un archivo
# 4 es seguro, pero podría ejecutar este comando cientos de veces al día, por lo que es tedioso. # 5 está cerca de ser seguro, pero ese archivo podría ser leído por alguien con acceso de root.
La página man de cURL dice (observe el texto en negrita):
-u/--user <user:password>
Especifique el nombre de usuario y la contraseña para usar para la autenticación del servidor.
-n/--netrc
y--netrc-optional
.Si solo le da el nombre de usuario (sin ingresar dos puntos), Curl le solicitará una contraseña.
Si utiliza un binario curl habilitado para SSPI y realiza la autenticación NTLM, puede obligar a curl a recoger el nombre de usuario y la contraseña de su entorno simplemente especificando un solo punto con esta opción:
-u :
He intentado configurar $USER
y $PASSWORD
(y $CURLOPT_PASSWORD
y otros) en el entorno, pero cURL no recoge ninguno de ellos cuando se invoca como curl -u : https://example.com
(ni funciona sin el -u :
.
No estoy haciendo NTLM, así que esto no funciona. A menos que me esté perdiendo algo.
¿Hay alguna manera de pasar credenciales para curl
solo a través del medio ambiente?
(Solución alternativa movida a una respuesta)
¿Hay alguna manera de pasar credenciales para
curl
solo a través del medio ambiente?
No, no creo que exista.
La documentación de CURLOPT_USERPWD creo que describe lo que necesita, pero esta es una opción que estaría disponible utilizando la biblioteca curl en otro idioma. PHP, Perl, C, etc.
El binario curl que ejecuta desde su caparazón es solo otra parte frontal de esa biblioteca, pero la forma en que cosas como CURLOPT_USERPWD pasan a la biblioteca a través del binario curl es mediante el uso de opciones de línea de comando en el binario.
En teoría, podría escribir su propio binario como front-end de la biblioteca curl, y escribir en soporte para variables de entorno.
Alternativamente, puede piratear la compatibilidad con el entorno ya que espera verlo en el binario de curl existente y compilar el suyo con las funciones locales.
Sin embargo, tenga en cuenta que incluso las variables de entorno pueden ser filtradas por su shell a la tabla de procesos. (¿Qué ves cuando ejecutas ps ewwp $$
?)
Tal vez un archivo .netrc con permisos restringidos sea la forma más segura de hacerlo. Tal vez necesite generar un archivo .netrc temporal para ser utilizado por la --netrc-file
curl.
Creo que debe elegir la solución menos arriesgada para su entorno o escribir algo en un lenguaje real que garantice la seguridad de manera adecuada.
Esta solución bash
parece que se ajusta mejor a mis necesidades. Es decentemente seguro, portátil y rápido.
#!/bin/bash
SRV="example.com"
URL="https://$SRV/path"
curl --netrc-file <(cat <<<"machine $SRV login $USER password $PASSWORD") "$URL"
Esto utiliza el <( command )
sustitución de proceso ( <( command )
ejecuta en un subconjunto para rellenar un descriptor de archivo que se entregará como un "archivo" al comando principal, que en este caso es curl
). La sustitución del proceso contiene una cadena aquí ( cat <<< text
, una variante del echo text
del echo text
que no incluirá nada en la lista de procesos), creando un descriptor de archivo para el archivo netrc para pasar credenciales al servidor web remoto .
La seguridad ofrecida por la sustitución de procesos es bastante buena: su descriptor de archivo no es un archivo temporal y no está disponible incluso desde otras llamadas en la misma instancia de shell, por lo que parece seguro en este contexto; un adversario tendría que excavar en la memoria o lanzar un ataque complicado para encontrar su contenido. Como la variable de entorno $PASSWORD
también está en la memoria, esto no debería aumentar la superficie de ataque .
Siempre que no haya utilizado export PASSWORD
, un truco como ps ewwp $$
no debe revelar la contraseña (como se indica en este comentario ). También sería aconsejable usar un nombre de variable menos obvio.
Aquí hay una versión simplificada e insegura del código anterior que puede ayudar a explicar cómo funciona:
#!/bin/sh
# INSECURE VERSION, DO NOT USE
SRV=example.com
URL="https://$SRV/path"
TMP=$(mktemp)
printf "machine %s login %s password %s/n" "$SRV" "$USER" "$PASSWORD" > "$TMP"
curl --netrc-file "$TMP" "$URL"
rm -f "$TMP"
Esta versión insegura tiene muchos defectos, todos los cuales se resuelven en la versión anterior:
- Almacena la contraseña en un archivo (aunque ese archivo solo es legible para usted)
- Tiene muy brevemente la contraseña en una línea de comando
- El archivo temporal permanece hasta después de que
curl
exits - Ctrl + c se cerrará sin eliminar el archivo temporal
Algo de eso podría ser resuelto por:
#!/bin/sh
SRV=example.com
URL="https://$SRV/path"
TMP=$(mktemp /dev/shm/.XXXXX) # assumes /dev/shm is a ramdisk
trap "rm -f $TMP" 0 18
cat << EOF > "$TMP"
machine $SRV login $USER password $PASSWORD
EOF
(sleep 0.1; rm -f "$TMP") & # queue removing temp file in 0.1 seconds
curl --netrc-file "$TMP" "$URL"
Considero que esta versión es desordenada, subóptima y posiblemente menos segura (aunque es más portátil). También requiere una versión de sleep
que comprenda los decimales (y 0.1 segundos puede ser demasiado rápido si el sistema está muy cargado).
Originalmente, había publicado una solución que incluía un perl
una sola línea en mi pregunta, luego (con la ayuda de Etan Reisner ) trabajé con algunos mejores métodos antes de decidirme por este método de cadena aquí, que es tanto más liviano (más rápido) y más portátil.
En este punto, es lo suficientemente elegante como para considerarla como la "respuesta" en lugar de una "solución fea", por lo que la he migrado para ser la respuesta oficial. Le he dado a @ghoti un +1 por su respuesta , que indica correctamente que el programa de línea de comandos de cURL es incapaz de hacer lo que quiero por sí mismo, pero no estoy "aceptando" esa respuesta porque no ayuda a resolver el problema. problema.