Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
libcurl-security(3)	    Library Functions Manual	     libcurl-security(3)

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  encoun-
     tered  while  operating with potentially malicious servers on the Internet.
     It is a powerful library that 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 cur-
     rently running processes.

     To avoid these problems, never feed sensitive things to programs using com-
     mand 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 fire up a network ana-
     lyzer 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 modi-
     fied 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.

Certificates and Long-running Connections
     Certificate validation of encrypted connections  is  performed  immediately
     after  a  connection is established. That connection could be used for many
     subsequent transfers, even if the certificate used for  validation  expires
     or  is revoked, the local certificate bundle is changed in a way that would
     have caused that certificate to fail validation,  the  server  changes  its
     certificate  to  one  that  would have failed validation, or even if a com-
     pletely different server is brought up under the same hostname. This  could
     continue  for  many hours (or even years) after such a change occurs, which
     may not be desired behavior for some applications.

     Remedies:

     Use the CURLOPT_MAXLIFETIME_CONN(3) option to limit the amount of time that
     connections are used after they have been successfully  validated.  Further
     transfers require a new connection with validation performed again.

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
     only  HTTP. libcurl restricts the protocols allowed to be used in redirects
     for security reasons: only HTTP, HTTPS, FTP and FTPS  are	enabled  by  de-
     fault.  Applications may opt to restrict that set further.

     A	redirect to a file: URL would cause the libcurl to read (or write) arbi-
     trary files from the local file system. If the application returns the data
     back to the user (as would happen in some kinds of  CGI  scripts),  an  at-
     tacker   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 (except 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-inter-
     nal-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 run-
     ning libcurl, including servers hidden behind a firewall from the attacker.
     E.g.	   https://127.0.0.1/	      or	  https://intranet.exam-
     ple/delete-stuff.cgi?delete=all	or   tftp://bootp-server.example/pc-con-
     fig-data

     Applications can mitigate against	this  by  disabling  CURLOPT_FOLLOWLOCA-
     TION(3) and handling redirects itself, sanitizing URLs as necessary. Alter-
     nately,  an  app could leave CURLOPT_FOLLOWLOCATION(3) enabled but set CUR-
     LOPT_REDIR_PROTOCOLS_STR(3) and install a CURLOPT_OPENSOCKETFUNCTION(3)  or
     CURLOPT_PREREQFUNCTION(3)	callback  function  in which addresses are sani-
     tized 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),  CUR-
     LOPT_USERAGENT(3),  CURLOPT_REFERER(3)  and CURLOPT_RANGE(3), libcurl sends
     the headers as-is and does not apply any special sanitation  or  normaliza-
     tion 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  https://fuzzybunnies.example.com/ could actually resolve to the IP ad-
     dress of a server behind a firewall, such as 127.0.0.1 or 10.1.2.3.  Appli-
     cations  can  mitigate  against  this  by setting a CURLOPT_OPENSOCKETFUNC-
     TION(3) or CURLOPT_PREREQFUNCTION(3) and checking the address before a con-
     nection.

     All the malicious scenarios regarding  redirected	URLs  apply  equally  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 CUR-
     LOPT_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 CUR-
     LOPT_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 and in-
     stead 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  er-
     ror-prone	idea because of the many different ways a numerical IPv4 address
     can be specified and libcurl accepts: one to four dot-separated fields  us-
     ing one of or a mix of decimal, octal or hexadecimal encoding.

IPv6 Addresses
     libcurl  handles  IPv6  addresses	transparently  and as easily as IPv4 ad-
     dresses.  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 connec-
     tions but leave IPv6 connections wide open. In  some  cases,  setting  CUR-
     LOPT_IPRESOLVE(3)	to  CURL_IPRESOLVE_V4  can be used to limit resolved ad-
     dresses to IPv4 only and bypass these issues.

Uploads
     When uploading, a redirect can cause a local (or remote) file to  be  over-
     written.  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,  sani-
     tizing 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 user-
     name and password being sent in clear text to an HTTP server. Instead,  use
     CURLAUTH_ANYSAFE which ensures that the password is encrypted over the net-
     work, 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 per-
     forms some malicious action to  a	site  whose  authentication  is  already
     stored	   in	    a	    cookie.	  E.g.	      https://mail.exam-
     ple.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 ef-
     fect 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 down-
     loads.

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 cor-
     rect 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 in-
     ternal networks etc. This resulted in CVE-2019-15601 and the associated se-
     curity fix.

     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 lo-
     cal 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 make 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 set of special
     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 uninten-
     tionally, 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 27 different URL schemes. https:// might
     be what you expect, ftp:// or imap:// might be what the user gives your ap-
     plication. Also, cross-protocol operations might be done by using a partic-
     ular 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 ac-
	    cepts

     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 let the user provide data for parts of it? Or maybe filter in-
	    put to only allow specific choices? Remember that the naive approach
	    of appending a user-specified string to a base URL could still allow
	    unexpected	results  through use of characters like ../ or ? or Uni-
	    code characters or hiding characters using various escaping means.

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  identi-
     cally.

     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 set-
     ting 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 up-
     load 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  re-
     quests 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 ad-
     dress of your local IP interface to the remote server - even when for exam-
     ple 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 keeping the TCP connection open. This
     could effectively result in a denial-of-service attack.  The  CURLOPT_TIME-
     OUT(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)  op-
     tion  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  CUR-
     LOPT_USERAGENT(3),  CURLOPT_HTTPHEADER(3), CURLOPT_POSTFIELDS(3) and others
     that are used to generate structured data. Characters  like  embedded  car-
     riage returns or ampersands could allow the user to create additional head-
     ers 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	applica-
     tion 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  en-
     abled  by	applications  that fail to properly validate server TLS/SSL cer-
     tificates, 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 possi-
     ble help might also impose certain security related risks. Hostnames, user-
     names, 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 sen-
     sitive data.

     To avoid this problem, you must of course use your common sense. Often, you
     can edit out the sensitive data or  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  vari-
     able 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	descrip-
     tors 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.

     This feature was removed from curl in 8.8.0.

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 cre-
     dentials 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 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)

libcurl 			   2026-06-11		     libcurl-security(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=libcurl-security&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help