Skip to content

Forcer cURL à obtenir un mot de passe de l’environnement

Solution:

Cette bash la solution semble correspondre le mieux à mes besoins. C’est décemment sécurisé, portable et rapide.

#!/bin/bash
SRV="example.com"
URL="https://$SRV/path"
curl --netrc-file <(cat <<<"machine $SRV login $USER password $PASSWORD") "$URL"

Cela utilise la substitution de processus (<( command ) s’exécute command dans un sous-shell pour remplir un descripteur de fichier à remettre en tant que “fichier” à la commande parent, qui dans ce cas est curl). La substitution de processus contient une chaîne here-string (cat <<< text, une variante de echo text cela ne mettra rien dans votre liste de processus), créant un descripteur de fichier pour le fichier netrc afin de transmettre les informations d’identification au serveur Web distant.

La sécurité offerte par la substitution de processus est en fait assez solide : son descripteur de fichier est ne pas un fichier temporaire et n’est pas disponible même à partir d’autres appels dans la même instance de shell, cela semble donc sécurisé dans ce contexte ; un adversaire devrait creuser dans la mémoire ou lancer une attaque compliquée pour trouver son contenu. Depuis le $PASSWORD La variable d’environnement est également en mémoire, cela ne devrait pas augmenter la surface d’attaque.

Tant que vous n’avez pas utilisé export PASSWORD, une astuce comme ps ewwp $$ ne devrait pas révéler le mot de passe (comme indiqué dans ce commentaire). Il serait également sage d’utiliser un nom de variable moins évident.

Voici une version simplifiée non sécurisée du code ci-dessus qui peut aider à expliquer son fonctionnement :

#!/bin/sh
# INSECURE VERSION, DO NOT USE
SRV=example.com
URL="https://$SRV/path"
TMP=$(mktemp)
printf "machine %s login %s password %sn" "$SRV" "$USER" "$PASSWORD" > "$TMP"
curl --netrc-file "$TMP" "$URL"
rm -f "$TMP"

Cette version non sécurisée présente de nombreux défauts, tous résolus dans la version précédente :

  • Il stocke le mot de passe dans un fichier (bien que ce fichier ne soit lisible que par vous)
  • Il a très brièvement le mot de passe dans une ligne de commande
  • Le fichier temporaire reste jusqu’à après curl sorties
  • Ctrl+c quittera sans supprimer le fichier temporaire

Certains de ces problèmes pourraient être résolus par :

#!/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"

Je considère que cette version est désordonnée, sous-optimale et peut-être moins sécurisée (bien qu’elle soit plus portable). Il nécessite également une version de sleep qui comprend les décimales (et 0,1 seconde peut être trop rapide si le système est fortement chargé).


J’avais initialement posté une solution de contournement qui comprenait un perl une ligne dans ma question, puis (avec l’aide d’Etan Reisner) j’ai travaillé sur quelques meilleures méthodes avant de m’installer sur cette méthode ici-chaîne, qui est à la fois plus légère (plus rapide) et plus portable.

À ce stade, c’est suffisamment élégant pour que je le considère comme la “réponse” plutôt que comme une “solution de contournement laide”, donc je l’ai migré pour être cette réponse officielle. J’ai donné à @ghoti un +1 pour sa réponse, qui indique correctement que le programme de ligne de commande de cURL est incapable de faire ce que je veux tout seul, mais je n'”accepte” pas cette réponse car elle n’aide pas à résoudre le problème.

Existe-t-il un moyen de transmettre les informations d’identification à curl uniquement par l’environnement ?

Non, je ne pense pas qu’il y ait.

Je pense que la documentation CURLOPT_USERPWD décrit ce dont vous avez besoin, mais c’est une option qui serait disponible en utilisant la bibliothèque curl dans un autre langage. PHP, Perl, C, etc.

Le binaire curl que vous exécutez à partir de votre shell n’est qu’un autre frontal sur cette bibliothèque, mais la façon dont des choses comme CURLOPT_USERPWD sont transmises à la bibliothèque via le binaire curl se fait à l’aide d’options de ligne de commande sur le binaire.

Vous pouvez théoriquement écrire votre propre binaire en tant que frontal de la bibliothèque curl et écrire en support des variables d’environnement.

Vous pouvez alternativement pirater le support de l’environnement car vous espérez le voir dans le binaire curl existant et compiler le vôtre avec des fonctions locales.

Il faut se méfier, cependant, que même les variables d’environnement peuvent être divulguées par votre shell dans la table de processus. (Que vois-tu quand tu cours ps ewwp $$?)

Peut-être qu’un fichier .netrc avec des autorisations restreintes sera le moyen le plus sûr. Peut-être aurez-vous besoin de générer un fichier .netrc temporaire à utiliser par le --netrc-file option boucle.

Je pense que vous devez soit choisir la solution la moins risquée pour votre environnement, soit écrire quelque chose dans un vrai langage qui assure correctement la sécurité.

L’utilisateur “Tom, Bom” fournit une solution décente pour cela ici : https://coderwall.com/p/dsfmwa/securely-use-basic-auth-with-curl

curl --config - https://example.com <<< 'user = "username:password"'

Cela empêche les mots de passe d’apparaître dans la liste des processus, bien que cela ne réponde pas spécifiquement à la question initiale de l’OP :

Existe-t-il un moyen de transmettre des informations d’identification pour boucler uniquement via l’environnement ?

Je donne toujours des points à @ghoti pour avoir donné une réponse plus complète et informative.



Articles Similaires

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.