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
       encountered  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 com-
       monly 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 simi-
       lar 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 op-
       tion 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 pass-
       words 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	 pass-
       words in	plain text anywhere.

Clear Text Passwords
       Many  of	 the  protocols	 libcurl supports send name and	password unen-
       crypted 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 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	proto-
       col that	does not let snoopers see  your	 password:  Digest,  CRAM-MD5,
       Kerberos,  SPNEGO or NTLM authentication. Or even better: use authenti-
       cated 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 re-
       mote 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.

Certificates and Long-running Connections
       Certificate validation of encrypted connections	is  performed  immedi-
       ately  after a connection is established. That connection could be used
       for many	subsequent transfers, even if the certificate used for valida-
       tion 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  valida-
       tion,  or even if a completely 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	appli-
       cations.

       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 redi-
       rects 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 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 file system. 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  Ker-
       beros  is  in  use, any other URL type (except file:) that requires au-
       thentication is also at risk.  A	 redirect  such	 as  ftp://some-inter-
       nal-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.	    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.
       Alternately,  an	 app could leave CURLOPT_FOLLOWLOCATION(3) enabled but
       set CURLOPT_REDIR_PROTOCOLS_STR(3) and  install	a  CURLOPT_OPENSOCKET-
       FUNCTION(3) or CURLOPT_PREREQFUNCTION(3)	callback function in which ad-
       dresses 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),	  CUR-
       LOPT_COOKIE(3),	 CURLOPT_USERAGENT(3),	 CURLOPT_REFERER(3)  and  CUR-
       LOPT_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 re-
       quest 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 ad-
       dress 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  address  of  a  server behind a firewall, such as
       127.0.0.1 or 10.1.2.3. Applications can mitigate	against	this  by  set-
       ting  a	CURLOPT_OPENSOCKETFUNCTION(3) or CURLOPT_PREREQFUNCTION(3) and
       checking	the address before a connection.

       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 provid-
       ing  a  translation  service  might  happily  translate	 file://local-
       host/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://exam-
       ple.com/file_to_read and	instead	gets http://192.168.0.1/my_router_con-
       fig might print a file that would otherwise be protected	by  the	 fire-
       wall.

       Allowing	your application to connect to local hosts, be it the same ma-
       chine 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 sim-
       ilar 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	as easily as IPv4  ad-
       dresses.	  That	means  that a sanitizing function that filters out ad-
       dresses like 127.0.0.1 is not sufficient	 -  the	 equivalent  IPv6  ad-
       dresses	::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  ac-
       cessed  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 informa-
       tion  to	be sent	to an unknown second server. Applications can mitigate
       against this by disabling CURLOPT_FOLLOWLOCATION(3) and handling	 redi-
       rects 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.  In-
       stead,  use  CURLAUTH_ANYSAFE  which  ensures  that the password	is en-
       crypted 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. In-
       stead, 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 al-
       ready	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
       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 applica-
       tion wants to avoid that, keep control of what URLs to use and/or  pre-
       vent 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  at-
       tempts  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.

       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 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 spe-
       cial paths potentially make your	system access other hosts on your net-
       work. 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  precau-
       tions against.

       If your curl-using script allow a custom	URL do you also, perhaps unin-
       tentionally,  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 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 let	the user provide data for parts	of it? Or maybe	filter
	      input 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 Unicode 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 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 an-
       other 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	interface 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 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_MAXFILE-
       SIZE_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, caus-
       ing a denial-of-service.	This  can  be  mitigated  by  using  the  CUR-
       LOPT_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 em-
       bedded 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	 --re-
       mote-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  ma-
       licious 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) op-
       tion 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  le-
       gitimate	 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 edit out	the sensitive data or search/replace your true	infor-
       mation with faked data.

setuid applications using libcurl
       libcurl-using  applications  that set the 'setuid' bit to run with ele-
       vated 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 environ-
       ment 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  de-
       scriptors  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
       credentials may be left in freed	data.

Saving files
       libcurl	cannot protect against attacks where an	attacker has write ac-
       cess 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 su-
       per 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