Vous utilisez cURL avec un nom d'utilisateur et un mot de passe?

468

Je souhaite accéder à une URL qui nécessite un nom d'utilisateur / mot de passe. Je voudrais essayer d'y accéder avec curl. En ce moment, je fais quelque chose comme:

curl http://api.somesite.com/test/blah?something=123

J'ai une erreur. Je suppose que je dois spécifier un nom d'utilisateur et un mot de passe avec la commande ci-dessus.

Comment puis je faire ça?

user246114
la source

Réponses:

695

Utilisez l' -uindicateur pour inclure un nom d'utilisateur et curl vous demandera un mot de passe:

curl -u username http://example.com

Vous pouvez également inclure le mot de passe dans la commande, mais votre mot de passe sera alors visible dans l'historique bash:

curl -u username:password http://example.com
Finbarr
la source
109
Notez que si vous le faites à partir de la console, le mot de passe restera dans l'historique, ce qui est ... faux. Vous devez spécifier juste -u utilisateur et CURL vous demandera le mot de passe en mode sans écho.
Cristian Vrabie
25
@CristianVrabie Techniquement correct, mais incorrect si vous l'exécutez à partir d'un script automatisé qui n'autorise pas les invites. Serait curieux de trouver une solution à ce problème.
Ligemer
26
@OmarOthman si vous exécutez curl à partir d'un script, les informations d'identification (évidemment) ne se retrouveront pas dans votre historique, mais elles seront visibles dans ps (1). Correction:print -- '-u username:password' > somewhere && curl -K somewhere http://...
juste quelqu'un
7
Les variables d'environnement @Jay seront évaluées avant l'exécution de la commande. Le mot de passe sera toujours visible dans la sortie ps.
Robert Važan
8
Pour ne pas m'étendre sur ce point, mais je pense que ma réponse ( stackoverflow.com/a/27894407/758174 c'est-à-dire en utilisant --netrc-file) est plus sûre. Il garde le mot de passe hors de l'historique, ps, votre script, etc. C'est la seule forme que j'utilise dans tous mes scripts et pour toutes les utilisations authentifiées de curl.
Pierre D
255

Il est plus sûr de faire:

curl --netrc-file my-password-file http://example.com

... comme passer une simple chaîne utilisateur / mot de passe sur la ligne de commande, est une mauvaise idée.

Le format du fichier de mot de passe est (selon man curl):

machine <example.com> login <username> password <password>

Remarque:

  1. Le nom de la machine ne doit pas inclure https://ou similaire! Juste le nom d'hôte.
  2. Les mots « machine», « login» et « password» ne sont que des mots clés; les informations réelles sont celles qui se trouvent après ces mots clés.
Pierre D
la source
10
Oui, cela garde le mot de passe hors de la liste des processus et de l'historique des commandes. Manière de loin préférable de le faire, et seulement un peu plus de travail :)
AC Capehart
8
Cela devrait certainement être la réponse acceptée; les mots de passe sur la ligne de commande sont une pratique horrible. (Et c'est un fait largement connu.)
ELLIOTTCABLE
6
Vous pouvez également utiliser l'indicateur -K <file>ou --config <file>pour recevoir des indicateurs de boucle via un fichier ou une entrée standard. (Attention: à ne pas confondre avec -kou --insecure!)
Rufflewind
2
Cette méthode curl empêche les informations d'identification de l'historique et de l'état du processus, mais laisse le nom d'utilisateur et le mot de passe en texte clair dans le fichier my-password créant un autre vecteur d'attaque - pire que d'avoir des informations dans le fichier historique: bash, par exemple, restreint automatiquement les autorisations du fichier historique. Un problème similaire se pose si vous utilisez des variables d'environnement avec par exemple un script pour définir le nom d'utilisateur / mot de passe. Si le script n'est pas sécurisé, les informations d'identification ne le sont pas non plus.
Steven the Easily Amused
5
@SteventheEasilyAmused Je ne suis pas d'accord, il est préférable d'utiliser un .netrcfichier en clair avec des autorisations strictes appropriées, de sorte que seul votre utilisateur puisse le lire, que d'autres mécanismes (par exemple, les arguments de ligne de commande) qui permettent à d' autres utilisateurs de lire les informations.
Ken Williams
77

Ou la même chose mais une syntaxe différente

curl http://username:[email protected]/test/blah?something=123
Daniel Magnusson
la source
1
J'utilise cette syntaxe, car elle peut être utilisée dans beaucoup d'autres situations. Comme à partir d'un cmd Windows sans cURL et sans wGet, en utilisant start "" "http://username:[email protected]/test/blah?something=123". Il peut être lancé de n'importe où. Cela s'applique également aux connexions ftp; D
m3nda
9
Vous devez encoder l'URL du nom d'utilisateur et du mot de passe pour utiliser des caractères amusants
diachedelic
2
Je sais que la plupart des gens savent qu'il ne faut pas envoyer de mots de passe (ou même des noms d'utilisateur) dans l'URL comme cet exemple, car il est facile à renifler. Cela étant dit; Je ne le recommande pas, mais utilisez-le uniquement lorsque vous savez ce que vous faites.
LosManos
1
C'est suuuuuper archaïque et ne doit pas être utilisé. C'est à partir des jours FTP: o
Qix - MONICA A ÉTÉ BRUÉE
2
Malheureusement, cela laisse le mot de passe visible dans la liste des processus.
Mark Ribau
63

Vous pouvez également simplement envoyer le nom d'utilisateur en écrivant:

curl -u USERNAME http://server.example

Curl vous demandera alors le mot de passe, et le mot de passe ne sera pas visible à l'écran (ou si vous devez copier / coller la commande).

Kristian
la source
28

Pour passer le mot de passe en toute sécurité dans un script (c'est-à-dire l'empêcher de s'afficher avec ps auxf ou logs), vous pouvez le faire avec le drapeau -K- (lire la configuration de stdin) et un heredoc:

curl --url url -K- <<< "--user user:password"
Matt Fleming
la source
2
Merci pour la référence à l' --configoption (-K) ... peut-être une meilleure solution serait de mettre "--user user: password" dans un fichier et simplement -K the filepour n'avoir qu'une seule copie du mot de passe plutôt une copie dans chaque script . Il est beaucoup plus facile de sécuriser un seul fichier.
Chris Cogdon
1
Option similaire, où seul le mot de passe est dans le fichier: cat "${password_filepath}" | sed -e "s/^/-u ${username}:/" | curl --url "${url}" -K-. J'ai dû mettre -K-avant l'URL pour l'ancien bash macOS, YMMV.
Mark Ribau
12

Habituellement, la commande CURL est appelée

curl https://example.com\?param\=ParamValue -u USERNAME:PASSWORD

si vous n'avez pas de mot de passe ou si vous souhaitez ignorer l'invite de commande pour demander un mot de passe, laissez la section mot de passe vide.

c'est à dire curl https://example.com\?param\=ParamValue -u USERNAME:

Touseef Murtaza
la source
1
REMARQUE: le mot de passe serait visible dans l'historique du shell et la liste des processus.
Mark Ribau
10
curl -X GET -u username:password  {{ http://www.example.com/filename.txt }} -O
user128364
la source
1
REMARQUE: le mot de passe serait visible dans l'historique du shell et la liste des processus.
Mark Ribau
8

Pour que le mot de passe n'apparaisse pas dans votre .bash_history:

curl -u user:$(cat .password-file) http://example-domain.tld
sjas
la source
6
Dans ce cas, le mot de passe se retrouvera toujours dans la liste des processus, par exemple il est visible par quelqu'un qui le fait ps auxw |grep curlau bon moment. De même, le mot de passe sera enregistré s'il est exécuté viasudo
Adam Katz
1
Avec cette méthode, le mot de passe est alors présent dans un fichier (fichier .password) qui peut être plus précaire que l'historique .bash. La bonne partie à ce sujet, c'est que ce n'est que le mot de passe - l'URL et le nom d'utilisateur ne sont pas divulgués dans le fichier .password.
Steven the Easily Amused
7

assez facile, faites ce qui suit:

curl -X GET/POST/PUT <URL> -u username:password
Preyas
la source
Il n'y a aucune exigence de sécurité sur la question
Victor Polo De Gyves Montero
1
REMARQUE: le mot de passe serait visible dans l'historique du shell et la liste des processus
Mark Ribau
6

D'autres réponses ont suggéré à netrc de spécifier le nom d'utilisateur et le mot de passe, en fonction de ce que j'ai lu, je suis d'accord. Voici quelques détails de syntaxe:

https://ec.haxx.se/usingcurl-netrc.html

Comme d'autres réponses, je voudrais souligner la nécessité de prêter attention à la sécurité concernant cette question.

Bien que je ne sois pas un expert, j'ai trouvé ces liens perspicaces:

https://ec.haxx.se/cmdline-passwords.html

Résumer:

L'utilisation des versions cryptées des protocoles (HTTPS vs HTTP) (FTPS vs FTP) peut aider à éviter les fuites réseau.

L'utilisation de netrc peut aider à éviter les fuites de ligne de commande.

Pour aller plus loin, il semble que vous pouvez également crypter les fichiers netrc en utilisant gpg

https://brandur.org/fragments/gpg-curl

Avec cela, vos informations d'identification ne sont pas "au repos" (stockées) en texte brut.

Brian Davis
la source
5

En clair et simplement, le moyen le plus sûr serait d'utiliser des variables d'environnement pour stocker / récupérer vos informations d'identification. Ainsi une commande curl comme:

curl -Lk -XGET -u "${API_USER}:${API_HASH}" -b cookies.txt -c cookies.txt -- "http://api.somesite.com/test/blah?something=123"

Appellerait alors votre api reposante et passerait l'en- WWW_Authenticationtête http avec les valeurs encodées en Base64 de API_USERet API_HASH. Le -Lkjuste indique à curl de suivre les redirections http 30x et d'utiliser une gestion tls non sécurisée (ie ignorer les erreurs ssl). Alors que le double --est juste du sucre de syntaxe bash pour arrêter le traitement des drapeaux de ligne de commande. De plus, les indicateurs -b cookies.txtet -c cookies.txttraitent les cookies avec l' -benvoi de cookies et le -cstockage local des cookies.

Le manuel contient plus d' exemples de méthodes d' authentification .

Dwight Spencer
la source
1
Gardez à l'esprit que l'utilisation de "-Lk" peut vous ouvrir aux attaques de l'homme du milieu (MITM), alors soyez prudent avec cette option.
GuyPaddock
4
Cela ne fonctionne pas ... puisque bash développe ces variables pour vous, l'expansion apparaît dans la liste des processus.
Chris Cogdon
4

Le moyen le plus sûr de transmettre des informations d'identification à curl est d'être invité à les insérer. C'est ce qui se passe lors du passage du nom d'utilisateur comme suggéré précédemment ( -u USERNAME).

Mais que faire si vous ne pouvez pas transmettre le nom d'utilisateur de cette façon? Par exemple, le nom d'utilisateur peut devoir faire partie de l'URL et seul le mot de passe doit faire partie d'une charge utile json.

tl; dr: Voici comment utiliser curl en toute sécurité dans ce cas:

read -p "Username: " U; read -sp "Password: " P; curl --request POST -d "{\"password\":\"${P}\"}" https://example.com/login/${U}; unset P U

read demandera à la fois le nom d'utilisateur et le mot de passe à partir de la ligne de commande, et stockera les valeurs soumises dans deux variables qui peuvent être des références dans les commandes suivantes et finalement non définies.

Je vais expliquer pourquoi les autres solutions ne sont pas idéales.

Pourquoi les variables d'environnement sont-elles dangereuses

  1. Le mode d'accès et d'exposition du contenu d'une variable d'environnement ne peut pas être suivi (ps -eww) car l'environnement est implicitement disponible pour un processus
  2. Souvent, les applications saisissent tout l'environnement et le consignent à des fins de débogage ou de surveillance (parfois sur des fichiers journaux en clair sur le disque, en particulier après le blocage d'une application)
  3. Les variables d'environnement sont transmises aux processus enfants (cassant ainsi le principe du moindre privilège)
  4. Leur maintenance est un problème: les nouveaux ingénieurs ne savent pas qu'ils sont là et ne connaissent pas les exigences qui les entourent - par exemple, ne pas les transmettre aux sous-processus - car ils ne sont pas appliqués ou documentés.

Pourquoi est-il dangereux de le taper directement dans une commande sur la ligne de commande Parce que votre secret finit par être visible par tout autre utilisateur en cours d'exécution ps -auxcar il répertorie les commandes soumises pour chaque processus en cours d'exécution. Aussi parce que votre secret se retrouve alors dans l'historique de bash (une fois le shell terminé).

Pourquoi est-il dangereux de l'inclure dans un fichier local Une restriction d'accès POSIX stricte sur le fichier peut atténuer le risque dans ce scénario. Cependant, il s'agit toujours d'un fichier sur votre système de fichiers, non chiffré au repos.

Iammyr
la source
2
Il semble que cette méthode afficherait toujours le mot de passe dans la liste des processus?
Mark Ribau
4

J'avais le même besoin en bash (Ubuntu 16.04 LTS) et les commandes fournies dans les réponses n'ont pas fonctionné dans mon cas. J'ai dû utiliser:

curl -X POST -F 'username="$USER"' -F 'password="$PASS"' "http://api.somesite.com/test/blah?something=123"

Les guillemets doubles dans les -Farguments ne sont nécessaires que si vous utilisez des variables, donc à partir de la ligne de commande, ça ... -F 'username=myuser' ...ira.

Avis de sécurité pertinent: comme le souligne M. Mark Ribau dans les commentaires, cette commande affiche le mot de passe (variable $ PASS, développée) dans la liste de processus!

Marco
la source
1
On dirait que cela montre toujours la valeur de $ PASS dans la liste des processus?
Mark Ribau
Oui, malheureusement.
Marco
1

Si vous êtes sur un système doté de l'application Gnome keyring, une solution qui évite d'exposer directement le mot de passe consiste à utiliser gkeyring.py pour extraire le mot de passe du trousseau:

server=server.example.com
file=path/to/my/file
user=my_user_name
pass=$(gkeyring.py -k login -tnetwork -p user=$user,server=$server -1)

curl -u $user:$pass ftps://$server/$file -O
Eliot Blennerhassett
la source
1
REMARQUE: le mot de passe serait visible dans la liste des processus. (Et l'histoire si cela ne fait pas partie d'un script.)
Mark Ribau
1

C'est BEAUCOUP plus que l'OP demandé, mais comme c'est le meilleur résultat pour passer des mots de passe en toute sécurité curl, j'ajoute ces solutions ici pour ceux qui arrivent ici à la recherche de cela.


REMARQUE: -sarg for readcommand n'est pas POSIX et n'est donc pas disponible partout, il ne sera donc pas utilisé ci-dessous. Nous utiliserons stty -echoet à la stty echoplace.

REMARQUE: Toutes les variables bash ci-dessous pourraient à la place être déclarées comme locales si elles sont dans une fonction, plutôt que de les désactiver.

REMARQUE: perlest généralement disponible sur tous les systèmes que j'ai essayés car il s'agit d'une dépendance pour de nombreuses choses, alors rubyque ce pythonn'est pas le cas, utilisez-la perlici. Si vous pouvez garantir ruby/ pythonoù vous faites cela, vous pouvez remplacer la perlcommande par leur équivalent.

REMARQUE: testé dans bash3.2.57 sur macOS 10.14.4. Quelques petites traductions peuvent être nécessaires pour d'autres shells / installations.


Invitez en toute sécurité un utilisateur à saisir un mot de passe (réutilisable) pour boucler. Particulièrement utile si vous devez appeler plusieurs fois curl.

Pour les coques modernes, où echoest intégré (vérifier via which echo):

url='https://example.com'
printf "Username: "
read username
printf "Password: "
stty -echo  # disables echoing user input, POSIX equivalent for 'read -s'
read pass
printf "\n" # we need to move the line ahead
stty echo   # re-enable echoing user input
echo ${pass} | sed -e "s/^/-u ${username}:/" | curl --url "${url}" -K-
unset username
unset pass

Pour les shells plus anciens, où echoest quelque chose comme /bin/echo(où quoi que ce soit en écho peut être vu dans la liste des processus):
CETTE VERSION NE PEUT PAS RÉUTILISER LE MOT DE PASSE , voir plus bas à la place.

url='https://example.com'
printf "Username: "
read username
printf "Password: "
stty -echo  # disables echoing user input, POSIX equivalent for 'read -s'
perl -e '
    my $val=<STDIN>;
    chomp $val;
    print STDERR "\n";  # we need to move the line ahead, but not send a newline down the pipe
    print $val;
' | sed -e "s/^/-u ${username}:/" | curl --url "${url}" -K-
stty echo   # re-enable echoing user input
unset username



Si vous avez besoin de stocker temporairement le mot de passe dans un fichier, de le réutiliser pour plusieurs commandes avant de l'effacer (par exemple, parce que vous utilisez des fonctions de réutilisation de code et que vous ne voulez pas répéter le code et ne pouvez pas transmettre la valeur via écho). (Oui, ceux-ci sont un peu artificiels car ils ne sont pas des fonctions dans différentes bibliothèques; j'ai essayé de les réduire au minimum de code pour le montrer.)

Lorsque l'écho est intégré (cela est particulièrement artificiel, car l'écho est intégré, mais fourni pour être complet):

url='https://example.com'
filepath="$(mktemp)"  # random path, only readable by current user
printf "Username: "
read username
printf "Password: "
stty -echo  # disables echoing user input, POSIX equivalent for 'read -s'
read pass
echo "${pass}" > "${filepath}"
unset pass
printf "\n" # we need to move the line ahead
stty echo   # re-enable echoing user input

cat "${filepath}" | sed -e "s/^/-u ${username}:/" | curl --url "${url}" -K-

rm "${filepath}"  # don't forget to delete the file when done!!
unset username

Quand l'écho est quelque chose comme /bin/echo:

url='https://example.com'
filepath="$(mktemp)"  # random path, only readable by current user
printf "Username: "
read username
printf "Password: "
stty -echo  # disables echoing user input, POSIX equivalent for 'read -s'
$(perl -e '
    my $val=<STDIN>;
    chomp $val;
    open(my $fh, ">", $ARGV[0]) or die "Could not open file \"$ARGV[0]\" $\!";
    print $fh $val;
    close $fh;
' "$filepath")
printf "\n" # we need to move the line ahead
stty echo   # re-enable echoing user input

cat "${filepath}" | sed -e "s/^/-u ${username}:/" | curl --url "${url}" -K-

rm "${filepath}"  # don't forget to delete the file when done!!
unset username
Mark Ribau
la source