37

Here’s an example request we can make to the GitHub API:

curl 'https://api.github.com/authorizations' --user "USERNAME"

This will prompt for the account password, to continue:

Enter host password for user 'USERNAME':

If we don’t want to get the prompt, we can provide the password at the same time as the username:

curl 'https://api.github.com/authorizations' --user "USERNAME:PASSWORD"

But is this method less secure? Does curl send all the data at once, or does it first setup a secure connection, and only then send the USERNAME and PASSWORD?

3 Answers 3

75

Regarding the connection there's no difference: the TLS is negotiated first and the HTTP request is secured by the TLS.

Locally this might be less secure, because:

  • The password gets saved to the command history (~/.bash_history) as a part of the command. Note: This can be avoided by adding a space in front of the command before running it (provided you have the setting ignorespace in variable HISTCONTROL).
  • On a shared system, it will usually be visible to others in ps, top and such, or by reading /proc/$pid/cmdline, for as long as the command is running.
  • Storing the password unsecured in a script might pose a security risk, depending on where the script itself is stored.
6
  • 1
    Then you must keep the script in a safe place. I'd recommend 700 permissions. Commented Mar 16, 2019 at 12:40
  • 7
    to solve the issue with .bash_history you could just prepend a space in front of your command. This way it doesn't get saved to history. (further info over here: unix.stackexchange.com/questions/115917/… )
    – Anticom
    Commented Mar 16, 2019 at 15:04
  • 8
    This doesn't solve the /proc/${pid}/cmdline issue (e.g., it showing up in ps output). If there are multiple users on a system, this is a great way to accidentally disclose a password. Commented Mar 16, 2019 at 17:26
  • 4
    @StephenTouset check here: unix.stackexchange.com/q/385339/135943. Curl password arguments do NOT appear in ps output, except possibly for a minuscule (and hard to demonstrate) time period after the curl command is invoked. Should not be relied on entirely for security but it’s pretty effective.
    – Wildcard
    Commented Mar 16, 2019 at 19:52
  • 1
    @dave_thompson_085 see my comment above. It is actually usually NOT visible in the places you mention, although there is a tiny race condition window where it may be.
    – Wildcard
    Commented Mar 16, 2019 at 19:57
11

But is this method less secure?

No, it is not if you use https. When you use HTTPS your complete transaction will be encrypted. But as @Esa mentioned it is insecure locally which you can avoid adding a space before your command so that the command will not be in your command history. If you are worried about exposing the command on the other users ps than hardening /proc would help you with that. Follow the link to enable hidepid.

Does curl send all the data at once, or does it first setup a secure connection, and only then send the USERNAME and PASSWORD?

No curl doesn't send all the data at once. Like other SSL/TLS connection, curl will initiate SSL handshake before passing any data.

You can inspect how your data is transferred with tcpdump, tshark or Wireshark like following, (after running tcpdump/tshark, run the curl command)

TCPDUMP

[root@arif]# tcpdump -i eth0 -n src host 192.168.1.1 and dst host 192.168.1.2 and port 443 -XX

Where,

  • -i: for listening on a specific interface which is in this case eth0
  • src host : Specifying source ip address
  • dst host : Specifying destination ip address
  • port: Specifying port 443 which is the default for SSL connection. You can change according to your requirement.
  • XX: For showing header, packet contents and link level header in HEX and ASCII.

You will start to see gibberish contents after a few packets. You also can grep your password from the packet with the following command,

[root@arif]# tcpdump -li eth0 -n src host 192.168.1.1 and dst host 192.168.1.2 and port 443 -XX | grep 'password'

If your password shows up there then your password did not get encrypted before transmission. Otherwise, you are okay.

TSHARK

[root@arif]# tshark -O tls "ip src 192.168.1.1 and ip dst 192.168.1.2" -x

Where,

  • -O: for mentioning protocol.
  • -x: for see packet contents.

you can grep your password with the above command too.

3

The best way to protect from local users is to use a ".netrc" file. The curl man page should have details on how to use it.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .