Provided by: libcurl4-doc_8.9.1-2ubuntu2_all bug

NAME

       libcurl-security - security considerations when using libcurl

Security

       The  libcurl  project  takes  security  seriously. The library is written with caution and
       precautions are taken to mitigate many kinds of risks  encountered  while  operating  with
       potentially  malicious  servers  on the Internet. It is a powerful library, however, which
       allows application writers to make trade-offs between ease  of  writing  and  exposure  to
       potential  risky  operations.  If used the right way, you can use libcurl to transfer data
       pretty safely.

       Many applications are used in closed networks where users and servers  can  (possibly)  be
       trusted,  but many others are used on arbitrary servers and are fed input from potentially
       untrusted users. Following is  a  discussion  about  some  risks  in  the  ways  in  which
       applications  commonly  use  libcurl  and  potential mitigations of those risks. It is not
       comprehensive, but shows classes of attacks that robust applications should consider.  The
       Common Weakness Enumeration project at https://cwe.mitre.org/ is a good reference for many
       of these and similar types of weaknesses of which application writers should be aware.

Command Lines

       If you use a command line tool (such as curl) that uses libcurl, and you give  options  to
       the tool on the command line those options can get read by other users of your system when
       they use ps or other tools to list currently running processes.

       To avoid these problems, never feed  sensitive  things  to  programs  using  command  line
       options. Write them to a protected file and use the -K option to avoid this.

.netrc

       .netrc  is  a pretty handy file/feature that allows you to login quickly and automatically
       to frequently visited sites. The file contains passwords in  clear  text  and  is  a  real
       security  risk.  In some cases, your .netrc is also stored in a home directory that is NFS
       mounted or used on another network based file system, so the  clear  text  password  flies
       through your network every time anyone reads that file.

       For applications that enable .netrc use, a user who manage to set the right URL might then
       be possible to pass on passwords.

       To avoid these problems, do not use .netrc files and never store passwords in  plain  text
       anywhere.

Clear Text Passwords

       Many  of  the  protocols libcurl supports send name and password unencrypted as clear text
       (HTTP Basic authentication, FTP, TELNET etc). It is easy for anyone on your network  or  a
       network  nearby  yours  to  just  fire  up  a  network analyzer tool and eavesdrop on your
       passwords. Do not let the fact that HTTP Basic uses base64  encoded  passwords  fool  you.
       They  may  not look readable at a first glance, but they are easily "deciphered" by anyone
       within seconds.

       To avoid this problem, use an authentication mechanism or other protocol that does not let
       snoopers  see your password: Digest, CRAM-MD5, Kerberos, SPNEGO or NTLM authentication. Or
       even better: use authenticated protocols that protect the entire connection and everything
       sent over it.

Unauthenticated Connections

       Protocols  that  do  not  have  any  form  of cryptographic authentication cannot with any
       certainty know that they communicate with the right remote server.

       If your application is using a fixed scheme or fixed hostname, it is not safe as  long  as
       the  connection  is unauthenticated. There can be a man-in-the-middle or in fact the whole
       server might have been replaced by an evil actor.

       Unauthenticated protocols are unsafe. The data that comes  back  to  curl  may  have  been
       injected  by an attacker. The data that curl sends might be modified before it reaches the
       intended server. If it even reaches the intended server at all.

       Remedies:

       Restrict operations to authenticated transfers
              Use authenticated protocols protected with HTTPS or SSH.

       Make sure the server's certificate etc is verified
              Never ever switch off certificate verification.

Redirects

       The CURLOPT_FOLLOWLOCATION(3) option automatically follows HTTP redirects sent by a remote
       server. These redirects can refer to any kind of URL, not just HTTP. libcurl restricts the
       protocols allowed to be used in redirects for security reasons: only HTTP, HTTPS, FTP  and
       FTPS are enabled by default. Applications may opt to restrict that set further.

       A  redirect to a file: URL would cause the libcurl to read (or write) arbitrary files from
       the local filesystem. If the application returns the data  back  to  the  user  (as  would
       happen  in  some  kinds of CGI scripts), an attacker could leverage this to read otherwise
       forbidden data (e.g.  file://localhost/etc/passwd).

       If authentication credentials are stored in the ~/.netrc file, or Kerberos is in use,  any
       other  URL  type (not just file:) that requires authentication is also at risk. A redirect
       such as ftp://some-internal-server/private-file would  then  return  data  even  when  the
       server is password protected.

       In  the  same  way,  if  an  unencrypted  SSH private key has been configured for the user
       running the libcurl application, SCP: or SFTP: URLs could access password  or  private-key
       protected resources, e.g. sftp://user@some-internal-server/etc/passwd

       The  CURLOPT_REDIR_PROTOCOLS_STR(3)  and  CURLOPT_NETRC(3) options can be used to mitigate
       against this kind of attack.

       A redirect can also specify a location available only  on  the  machine  running  libcurl,
       including  servers  hidden behind a firewall from the attacker.  E.g. http://127.0.0.1/ or
       http://intranet/delete-stuff.cgi?delete=all or tftp://bootp-server/pc-config-data

       Applications can mitigate against this by disabling CURLOPT_FOLLOWLOCATION(3) and handling
       redirects   itself,  sanitizing  URLs  as  necessary.  Alternately,  an  app  could  leave
       CURLOPT_FOLLOWLOCATION(3) enabled but set  CURLOPT_REDIR_PROTOCOLS_STR(3)  and  install  a
       CURLOPT_OPENSOCKETFUNCTION(3)  or  CURLOPT_PREREQFUNCTION(3)  callback  function  in which
       addresses are sanitized before use.

CRLF in Headers

       For  all  options  in  libcurl  which  specify  headers,  including  but  not  limited  to
       CURLOPT_HTTPHEADER(3),  CURLOPT_PROXYHEADER(3),  CURLOPT_COOKIE(3),  CURLOPT_USERAGENT(3),
       CURLOPT_REFERER(3) and CURLOPT_RANGE(3), libcurl sends the  headers  as-is  and  does  not
       apply any special sanitation or normalization to them.

       If  you allow untrusted user input into these options without sanitizing CRLF sequences in
       them, someone malicious may be able to modify the request in a way you did not intend such
       as injecting new headers.

Local Resources

       A  user who can control the DNS server of a domain being passed in within a URL can change
       the address of the host to a local, private  address  which  a  server-side  libcurl-using
       application  could then use. E.g. the innocuous URL http://fuzzybunnies.example.com/ could
       actually resolve to the IP address of a server behind a firewall,  such  as  127.0.0.1  or
       10.1.2.3.     Applications     can     mitigate     against     this    by    setting    a
       CURLOPT_OPENSOCKETFUNCTION(3) or CURLOPT_PREREQFUNCTION(3) and checking the address before
       a connection.

       All the malicious scenarios regarding redirected URLs apply just as well to non-redirected
       URLs, if the user is allowed to specify an arbitrary URL that could  point  to  a  private
       resource.  For  example, a web app providing a translation service might happily translate
       file://localhost/etc/passwd and display the result. Applications can mitigate against this
       with  the  CURLOPT_PROTOCOLS_STR(3) option as well as by similar mitigation techniques for
       redirections.

       A malicious FTP server could in response to the PASV command return an IP address and port
       number  for  a server local to the app running libcurl but behind a firewall. Applications
       can  mitigate  against  this  by   using   the   CURLOPT_FTP_SKIP_PASV_IP(3)   option   or
       CURLOPT_FTPPORT(3).

       Local  servers  sometimes  assume  local  access  comes from friends and trusted users. An
       application  that  expects  https://example.com/file_to_read   that   and   instead   gets
       http://192.168.0.1/my_router_config  might  print a file that would otherwise be protected
       by the firewall.

       Allowing your application to connect to local hosts, be it the same machine that runs  the
       application  or  a  machine  on the same local network, might be possible to exploit by an
       attacker who then perhaps can "port-scan" the particular hosts  -  depending  on  how  the
       application and servers acts.

IPv4 Addresses

       Some  users  might  be  tempted  to  filter  access to local resources or similar based on
       numerical IPv4 addresses used in URLs. This is a bad and error-prone idea because  of  the
       many  different ways a numerical IPv4 address can be specified and libcurl accepts: one to
       four dot-separated fields using one of or a mix of decimal, octal or hexadecimal encoding.

IPv6 Addresses

       libcurl handles IPv6 addresses transparently and just as easily as  IPv4  addresses.  That
       means  that  a  sanitizing  function  that  filters  out  addresses  like 127.0.0.1 is not
       sufficient  -  the  equivalent  IPv6  addresses  ::1,  ::,  0:00::0:1,   ::127.0.0.1   and
       ::ffff:7f00:1  supplied  somehow  by an attacker would all bypass a naive filter and could
       allow access to undesired local resources. IPv6  also  has  special  address  blocks  like
       link-local  and  site-local  that  generally  should  not  be  accessed  by  a server-side
       libcurl-using application. A poorly  configured  firewall  installed  in  a  data  center,
       organization  or  server  may  also be configured to limit IPv4 connections but leave IPv6
       connections wide open. In some cases, setting  CURLOPT_IPRESOLVE(3)  to  CURL_IPRESOLVE_V4
       can be used to limit resolved addresses to IPv4 only and bypass these issues.

Uploads

       When  uploading,  a  redirect  can  cause  a  local  (or  remote)  file to be overwritten.
       Applications must not allow any unsanitized  URL  to  be  passed  in  for  uploads.  Also,
       CURLOPT_FOLLOWLOCATION(3)  should not be used on uploads. Instead, the applications should
       consider handling redirects itself, sanitizing each URL first.

Authentication

       Use of CURLOPT_UNRESTRICTED_AUTH(3) could cause authentication information to be  sent  to
       an   unknown   second   server.  Applications  can  mitigate  against  this  by  disabling
       CURLOPT_FOLLOWLOCATION(3) and handling redirects itself, sanitizing where necessary.

       Use of the CURLAUTH_ANY  option  to  CURLOPT_HTTPAUTH(3)  could  result  in  username  and
       password  being  sent in clear text to an HTTP server. Instead, use CURLAUTH_ANYSAFE which
       ensures that the password is encrypted over the network, or else fail the request.

       Use of the CURLUSESSL_TRY option  to  CURLOPT_USE_SSL(3)  could  result  in  username  and
       password  being  sent  in  clear text to an FTP server. Instead, use CURLUSESSL_CONTROL to
       ensure that an encrypted connection is used or else fail the request.

Cookies

       If cookies are enabled and cached, then a user could  craft  a  URL  which  performs  some
       malicious  action  to  a  site  whose  authentication  is already stored in a cookie. E.g.
       http://mail.example.com/delete-stuff.cgi?delete=all Applications can mitigate against this
       by disabling cookies or clearing them between requests.

Dangerous SCP URLs

       SCP  URLs  can contain raw commands within the scp: URL, which is a side effect of how the
       SCP protocol is designed. E.g.
         scp://user:pass@host/a;date >/tmp/test;
       Applications must not allow unsanitized SCP: URLs to be passed in for downloads.

file://

       By default curl and libcurl support file:// URLs. Such a  URL  is  always  an  access,  or
       attempted  access,  to  a  local  resource.  If your application wants to avoid that, keep
       control of what URLs to use and/or prevent curl/libcurl from using the protocol.

       By default, libcurl prohibits redirects to file:// URLs.

Warning: file:// on Windows

       The Windows operating system tries automatically, and without any way for applications  to
       disable it, to establish a connection to another host over the network and access it (over
       SMB or other protocols), if only the correct file path is accessed.

       When first realizing this, the curl team tried to filter out such  attempts  in  order  to
       protect  applications  for  inadvertent  probes of for example internal networks etc. This
       resulted in CVE-2019-15601 and the associated security fix.

       However, we have since been made aware of the fact that the  previous  fix  was  far  from
       adequate  as  there  are  several  other  ways  to accomplish more or less the same thing:
       accessing a remote host over the network instead of the local file system.

       The conclusion we have come to is that this is  a  weakness  or  feature  in  the  Windows
       operating system itself, that we as an application cannot safely protect users against. It
       would just be a whack-a-mole race we do not want to participate in.  There  are  too  many
       ways to do it and there is no knob we can use to turn off the practice.

       If  you use curl or libcurl on Windows (any version), disable the use of the FILE protocol
       in curl or be prepared that accesses to a range of "magic  paths"  potentially  make  your
       system access other hosts on your network. curl cannot protect you against this.

What if the user can set the URL

       Applications  may  find  it tempting to let users set the URL that it can work on. That is
       probably fine, but opens up for mischief and trickery that you as  an  application  author
       may want to address or take precautions against.

       If  your  curl-using script allow a custom URL do you also, perhaps unintentionally, allow
       the user to pass other options to the  curl  command  line  if  creative  use  of  special
       characters are applied?

       If  the user can set the URL, the user can also specify the scheme part to other protocols
       that you did not intend for users to use and perhaps did not consider. curl supports  over
       20 different URL schemes. "http://" might be what you thought, "ftp://" or "imap://" might
       be what the user gives your application. Also, cross-protocol operations might be done  by
       using a particular scheme in the URL but point to a server doing a different protocol on a
       non-standard port.

       Remedies:

       Use --proto
              curl command lines can use --proto to limit what URL schemes it accepts

       Use CURLOPT_PROTOCOLS_STR
              libcurl programs can use CURLOPT_PROTOCOLS_STR(3) to  limit  what  URL  schemes  it
              accepts

       consider not allowing the user to set the full URL
              Maybe just let the user provide data for parts of it? Or maybe filter input to only
              allow specific choices?

RFC 3986 vs WHATWG URL

       curl supports URLs mostly according to how they are defined in RFC 3986, and has  done  so
       since the beginning.

       Web browsers mostly adhere to the WHATWG URL Specification.

       This  deviance  makes  some  URLs  copied  between  browsers  (or  returned  over HTTP for
       redirection) and curl not work the same way. It can also cause problems if an  application
       parses  URLs  differently  from libcurl and makes different assumptions about a link. This
       can mislead users into getting the wrong thing, connecting to the wrong host or  otherwise
       not working identically.

       Within  an application, this can be mitigated by always using the curl_url(3) API to parse
       URLs, ensuring that they are parsed the same way as within libcurl itself.

FTP uses two connections

       When performing an FTP transfer, two TCP connections are used:  one  for  setting  up  the
       transfer and one for the actual data.

       FTP  is not only unauthenticated, but the setting up of the second transfer is also a weak
       spot. The second connection to use for data, is either setup with  the  PORT/EPRT  command
       that  makes  the server connect back to the client on the given IP+PORT, or with PASV/EPSV
       that makes the server setup a port to listen to and tells the client to connect to a given
       IP+PORT.

       Again,   unauthenticated   means   that   the  connection  might  be  meddled  with  by  a
       man-in-the-middle or that there is a malicious server pretending to be the right one.

       A malicious FTP server can respond  to  PASV  commands  with  the  IP+PORT  of  a  totally
       different machine. Perhaps even a third party host, and when there are many clients trying
       to connect to that third party, it could create a Distributed Denial-Of-Service attack out
       of  it.  If  the client makes an upload operation, it can make the client send the data to
       another site. If the attacker can affect what data the client uploads, it can be  made  to
       work  as  a HTTP request and then the client could be made to issue HTTP requests to third
       party hosts.

       An attacker that manages to control curl's command line options can tell curl to  send  an
       FTP  PORT  command  to  ask the server to connect to a third party host instead of back to
       curl.

       The fact that FTP uses two connections makes it vulnerable in a way that is hard to avoid.

Active FTP passes on the local IP address

       If you use curl/libcurl to do active FTP transfers, curl passes on  the  address  of  your
       local  IP  to  the  remote  server  - even when for example using a SOCKS or HTTP proxy in
       between curl and the target server.

Denial of Service

       A malicious server could cause libcurl to effectively hang by sending data slowly, or even
       no  data at all but just keeping the TCP connection open. This could effectively result in
       a  denial-of-service  attack.  The  CURLOPT_TIMEOUT(3)  and/or  CURLOPT_LOW_SPEED_LIMIT(3)
       options can be used to mitigate against this.

       A malicious server could cause libcurl to download an infinite amount of data, potentially
       causing system resources to be exhausted resulting  in  a  system  or  application  crash.
       Setting  the  CURLOPT_MAXFILESIZE_LARGE(3) option is not sufficient to guard against this.
       Instead, applications should monitor the amount of  data  received  within  the  write  or
       progress callback and abort once the limit is reached.

       A   malicious   HTTP   server   could  cause  an  infinite  redirection  loop,  causing  a
       denial-of-service. This can be mitigated by using the CURLOPT_MAXREDIRS(3) option.

Arbitrary Headers

       User-supplied data must be sanitized  when  used  in  options  like  CURLOPT_USERAGENT(3),
       CURLOPT_HTTPHEADER(3),   CURLOPT_POSTFIELDS(3)  and  others  that  are  used  to  generate
       structured data. Characters like embedded carriage returns or ampersands could  allow  the
       user to create additional headers or fields that could cause malicious transactions.

Server-supplied Names

       A  server can supply data which the application may, in some cases, use as a filename. The
       curl command-line tool does this with --remote-header-name, using the Content-disposition:
       header  to generate a filename. An application could also use CURLINFO_EFFECTIVE_URL(3) to
       generate a filename from a server-supplied redirect URL. Special care  must  be  taken  to
       sanitize  such  names  to  avoid  the possibility of a malicious server supplying one like
       "/etc/passwd", "autoexec.bat", "prn:" or even ".bashrc".

Server Certificates

       A secure application should never use  the  CURLOPT_SSL_VERIFYPEER(3)  option  to  disable
       certificate  validation.  There are numerous attacks that are enabled by applications that
       fail to properly validate server TLS/SSL certificates, thus enabling a malicious server to
       spoof a legitimate one. HTTPS without validated certificates is potentially as insecure as
       a plain HTTP connection.

Showing What You Do

       Relatedly, be aware that in situations when you have problems with libcurl and ask someone
       for  help,  everything  you  reveal  in  order to get best possible help might also impose
       certain security related risks. Hostnames, usernames, paths, operating  system  specifics,
       etc.  (not  to  mention  passwords  of  course)  may  in fact be used by intruders to gain
       additional information of a potential target.

       Be sure to limit access to application logs if they could hold private or security-related
       data.  Besides  the  obvious  candidates  like  usernames and passwords, things like URLs,
       cookies or even filenames could also hold sensitive data.

       To avoid this problem, you must of course use your common sense. Often, you can just  edit
       out the sensitive data or just search/replace your true information with faked data.

setuid applications using libcurl

       libcurl-using  applications  that  set  the  'setuid' bit to run with elevated or modified
       rights also implicitly give that extra power to libcurl and this should only be done after
       careful considerations.

       Giving  setuid powers to the application means that libcurl can save files using those new
       rights (if for example the SSLKEYLOGFILE  environment  variable  is  set).  Also:  if  the
       application  wants  these  powers to read or manage secrets that the user is otherwise not
       able to view (like credentials for a login etc), it should be  noted  that  libcurl  still
       might  understand  proxy  environment  variables  that  allow the user to redirect libcurl
       operations to use a proxy controlled by the user.

File descriptors, fork and NTLM

       An application that uses libcurl and invokes fork() gets all file  descriptors  duplicated
       in the child process, including the ones libcurl created.

       libcurl  itself uses fork() and execl() if told to use the CURLAUTH_NTLM_WB authentication
       method which then invokes the helper command in a  child  process  with  file  descriptors
       duplicated. Make sure that only the trusted and reliable helper program is invoked!

Secrets in memory

       When  applications pass usernames, passwords or other sensitive data to libcurl to be used
       for upcoming transfers, those secrets are kept around as-is in memory. In many cases  they
       are stored in the heap for as long as the handle itself for which the options are set.

       If  an  attacker  can access the heap, like maybe by reading swap space or via a core dump
       file, such data might be accessible.

       Further, when eventually closing a handle and the secrets are no  longer  needed,  libcurl
       does  not  explicitly  clear memory before freeing it, so credentials may be left in freed
       data.

Saving files

       libcurl cannot protect against attacks where an attacker has  write  access  to  the  same
       directory where libcurl is directed to save files.

Cookies

       If libcurl is built with PSL (Public Suffix List) support, it detects and discards cookies
       that are specified for such suffix domains that should not be allowed to have cookies.

       if libcurl is not built with PSL support, it has no ability to stop super cookies.

Report Security Problems

       Should you detect or just suspect a security problem  in  libcurl  or  curl,  contact  the
       project  curl  security  team  immediately.  See  https://curl.se/dev/secprocess.html  for
       details.

SEE ALSO

       libcurl-thread(3)