• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1---
2c: Copyright (C) Daniel Stenberg, <daniel.se>, et al.
3SPDX-License-Identifier: curl
4Title: libcurl-security
5Section: 3
6Source: libcurl
7See-also:
8  - libcurl-thread (3)
9---
10<!-- markdown-link-check-disable -->
11# NAME
12
13libcurl-security - security considerations when using libcurl
14
15# Security
16
17The libcurl project takes security seriously. The library is written with
18caution and precautions are taken to mitigate many kinds of risks encountered
19while operating with potentially malicious servers on the Internet. It is a
20powerful library, however, which allows application writers to make trade-offs
21between ease of writing and exposure to potential risky operations. If used
22the right way, you can use libcurl to transfer data pretty safely.
23
24Many applications are used in closed networks where users and servers can
25(possibly) be trusted, but many others are used on arbitrary servers and are
26fed input from potentially untrusted users. Following is a discussion about
27some risks in the ways in which applications commonly use libcurl and
28potential mitigations of those risks. It is not comprehensive, but shows
29classes of attacks that robust applications should consider. The Common
30Weakness Enumeration project at https://cwe.mitre.org/ is a good reference for
31many of these and similar types of weaknesses of which application writers
32should be aware.
33
34# Command Lines
35
36If you use a command line tool (such as curl) that uses libcurl, and you give
37options to the tool on the command line those options can get read by other
38users of your system when they use *ps* or other tools to list currently
39running processes.
40
41To avoid these problems, never feed sensitive things to programs using command
42line options. Write them to a protected file and use the -K option to avoid
43this.
44
45# .netrc
46
47.netrc is a pretty handy file/feature that allows you to login quickly and
48automatically to frequently visited sites. The file contains passwords in
49clear text and is a real security risk. In some cases, your .netrc is also
50stored in a home directory that is NFS mounted or used on another network
51based file system, so the clear text password flies through your network every
52time anyone reads that file.
53
54For applications that enable .netrc use, a user who manage to set the right
55URL might then be possible to pass on passwords.
56
57To avoid these problems, do not use .netrc files and never store passwords in
58plain text anywhere.
59
60# Clear Text Passwords
61
62Many of the protocols libcurl supports send name and password unencrypted as
63clear text (HTTP Basic authentication, FTP, TELNET etc). It is easy for anyone
64on your network or a network nearby yours to just fire up a network analyzer
65tool and eavesdrop on your passwords. Do not let the fact that HTTP Basic uses
66base64 encoded passwords fool you. They may not look readable at a first
67glance, but they are easily "deciphered" by anyone within seconds.
68
69To avoid this problem, use an authentication mechanism or other protocol that
70does not let snoopers see your password: Digest, CRAM-MD5, Kerberos, SPNEGO or
71NTLM authentication. Or even better: use authenticated protocols that protect
72the entire connection and everything sent over it.
73
74# Unauthenticated Connections
75
76Protocols that do not have any form of cryptographic authentication cannot
77with any certainty know that they communicate with the right remote server.
78
79If your application is using a fixed scheme or fixed hostname, it is not safe
80as long as the connection is unauthenticated. There can be a man-in-the-middle
81or in fact the whole server might have been replaced by an evil actor.
82
83Unauthenticated protocols are unsafe. The data that comes back to curl may
84have been injected by an attacker. The data that curl sends might be modified
85before it reaches the intended server. If it even reaches the intended server
86at all.
87
88Remedies:
89
90## Restrict operations to authenticated transfers
91
92Use authenticated protocols protected with HTTPS or SSH.
93
94## Make sure the server's certificate etc is verified
95
96Never ever switch off certificate verification.
97
98# Redirects
99
100The CURLOPT_FOLLOWLOCATION(3) option automatically follows HTTP
101redirects sent by a remote server. These redirects can refer to any kind of
102URL, not just HTTP. libcurl restricts the protocols allowed to be used in
103redirects for security reasons: only HTTP, HTTPS, FTP and FTPS are
104enabled by default. Applications may opt to restrict that set further.
105
106A redirect to a file: URL would cause the libcurl to read (or write) arbitrary
107files from the local filesystem. If the application returns the data back to
108the user (as would happen in some kinds of CGI scripts), an attacker could
109leverage this to read otherwise forbidden data (e.g.
110**file://localhost/etc/passwd**).
111
112If authentication credentials are stored in the ~/.netrc file, or Kerberos is
113in use, any other URL type (not just file:) that requires authentication is
114also at risk. A redirect such as **ftp://some-internal-server/private-file** would
115then return data even when the server is password protected.
116
117In the same way, if an unencrypted SSH private key has been configured for the
118user running the libcurl application, SCP: or SFTP: URLs could access password
119or private-key protected resources,
120e.g. **sftp://user@some-internal-server/etc/passwd**
121
122The CURLOPT_REDIR_PROTOCOLS(3) and CURLOPT_NETRC(3) options can be
123used to mitigate against this kind of attack.
124
125A redirect can also specify a location available only on the machine running
126libcurl, including servers hidden behind a firewall from the attacker.
127E.g. **http://127.0.0.1/** or **http://intranet/delete-stuff.cgi?delete=all** or
128**tftp://bootp-server/pc-config-data**
129
130Applications can mitigate against this by disabling
131CURLOPT_FOLLOWLOCATION(3) and handling redirects itself, sanitizing URLs
132as necessary. Alternately, an app could leave CURLOPT_FOLLOWLOCATION(3)
133enabled but set CURLOPT_REDIR_PROTOCOLS(3) and install a
134CURLOPT_OPENSOCKETFUNCTION(3) or CURLOPT_PREREQFUNCTION(3) callback
135function in which addresses are sanitized before use.
136
137# CRLF in Headers
138
139For all options in libcurl which specify headers, including but not limited to
140CURLOPT_HTTPHEADER(3), CURLOPT_PROXYHEADER(3),
141CURLOPT_COOKIE(3), CURLOPT_USERAGENT(3), CURLOPT_REFERER(3)
142and CURLOPT_RANGE(3), libcurl sends the headers as-is and does not apply
143any special sanitation or normalization to them.
144
145If you allow untrusted user input into these options without sanitizing CRLF
146sequences in them, someone malicious may be able to modify the request in a
147way you did not intend such as injecting new headers.
148
149# Local Resources
150
151A user who can control the DNS server of a domain being passed in within a URL
152can change the address of the host to a local, private address which a
153server-side libcurl-using application could then use. E.g. the innocuous URL
154**http://fuzzybunnies.example.com/** could actually resolve to the IP
155address of a server behind a firewall, such as 127.0.0.1 or
15610.1.2.3. Applications can mitigate against this by setting a
157CURLOPT_OPENSOCKETFUNCTION(3) or CURLOPT_PREREQFUNCTION(3) and
158checking the address before a connection.
159
160All the malicious scenarios regarding redirected URLs apply just as well to
161non-redirected URLs, if the user is allowed to specify an arbitrary URL that
162could point to a private resource. For example, a web app providing a
163translation service might happily translate **file://localhost/etc/passwd**
164and display the result. Applications can mitigate against this with the
165CURLOPT_PROTOCOLS(3) option as well as by similar mitigation techniques
166for redirections.
167
168A malicious FTP server could in response to the PASV command return an IP
169address and port number for a server local to the app running libcurl but
170behind a firewall. Applications can mitigate against this by using the
171CURLOPT_FTP_SKIP_PASV_IP(3) option or CURLOPT_FTPPORT(3).
172
173Local servers sometimes assume local access comes from friends and trusted
174users. An application that expects https://example.com/file_to_read that and
175instead gets http://192.168.0.1/my_router_config might print a file that would
176otherwise be protected by the firewall.
177
178Allowing your application to connect to local hosts, be it the same machine
179that runs the application or a machine on the same local network, might be
180possible to exploit by an attacker who then perhaps can "port-scan" the
181particular hosts - depending on how the application and servers acts.
182
183# IPv4 Addresses
184
185Some users might be tempted to filter access to local resources or similar
186based on numerical IPv4 addresses used in URLs. This is a bad and error-prone
187idea because of the many different ways a numerical IPv4 address can be
188specified and libcurl accepts: one to four dot-separated fields using one of
189or a mix of decimal, octal or hexadecimal encoding.
190
191# IPv6 Addresses
192
193libcurl handles IPv6 addresses transparently and just as easily as IPv4
194addresses. That means that a sanitizing function that filters out addresses
195like 127.0.0.1 is not sufficient - the equivalent IPv6 addresses **::1**,
196**::**, **0:00::0:1**, **::127.0.0.1** and **::ffff:7f00:1** supplied
197somehow by an attacker would all bypass a naive filter and could allow access
198to undesired local resources. IPv6 also has special address blocks like
199link-local and site-local that generally should not be accessed by a
200server-side libcurl-using application. A poorly configured firewall installed
201in a data center, organization or server may also be configured to limit IPv4
202connections but leave IPv6 connections wide open. In some cases, setting
203CURLOPT_IPRESOLVE(3) to CURL_IPRESOLVE_V4 can be used to limit resolved
204addresses to IPv4 only and bypass these issues.
205
206# Uploads
207
208When uploading, a redirect can cause a local (or remote) file to be
209overwritten. Applications must not allow any unsanitized URL to be passed in
210for uploads. Also, CURLOPT_FOLLOWLOCATION(3) should not be used on
211uploads. Instead, the applications should consider handling redirects itself,
212sanitizing each URL first.
213
214# Authentication
215
216Use of CURLOPT_UNRESTRICTED_AUTH(3) could cause authentication
217information to be sent to an unknown second server. Applications can mitigate
218against this by disabling CURLOPT_FOLLOWLOCATION(3) and handling
219redirects itself, sanitizing where necessary.
220
221Use of the CURLAUTH_ANY option to CURLOPT_HTTPAUTH(3) could result in
222user name and password being sent in clear text to an HTTP server. Instead,
223use CURLAUTH_ANYSAFE which ensures that the password is encrypted over the
224network, or else fail the request.
225
226Use of the CURLUSESSL_TRY option to CURLOPT_USE_SSL(3) could result in
227user name and password being sent in clear text to an FTP server. Instead,
228use CURLUSESSL_CONTROL to ensure that an encrypted connection is used or else
229fail the request.
230
231# Cookies
232
233If cookies are enabled and cached, then a user could craft a URL which
234performs some malicious action to a site whose authentication is already
235stored in a cookie. E.g.
236**http://mail.example.com/delete-stuff.cgi?delete=all** Applications can
237mitigate against this by disabling cookies or clearing them between requests.
238
239# Dangerous SCP URLs
240
241SCP URLs can contain raw commands within the scp: URL, which is a side effect
242of how the SCP protocol is designed. E.g.
243~~~
244  scp://user:pass@host/a;date >/tmp/test;
245~~~
246Applications must not allow unsanitized SCP: URLs to be passed in for
247downloads.
248
249# file://
250
251By default curl and libcurl support file:// URLs. Such a URL is always an
252access, or attempted access, to a local resource. If your application wants to
253avoid that, keep control of what URLs to use and/or prevent curl/libcurl from
254using the protocol.
255
256By default, libcurl prohibits redirects to file:// URLs.
257
258# Warning: file:// on Windows
259
260The Windows operating system tries automatically, and without any way for
261applications to disable it, to establish a connection to another host over the
262network and access it (over SMB or other protocols), if only the correct file
263path is accessed.
264
265When first realizing this, the curl team tried to filter out such attempts in
266order to protect applications for inadvertent probes of for example internal
267networks etc. This resulted in CVE-2019-15601 and the associated security fix.
268
269However, we have since been made aware of the fact that the previous fix was far
270from adequate as there are several other ways to accomplish more or less the
271same thing: accessing a remote host over the network instead of the local file
272system.
273
274The conclusion we have come to is that this is a weakness or feature in the
275Windows operating system itself, that we as an application cannot safely
276protect users against. It would just be a whack-a-mole race we do not want to
277participate in. There are too many ways to do it and there is no knob we can
278use to turn off the practice.
279
280If you use curl or libcurl on Windows (any version), disable the use of the
281FILE protocol in curl or be prepared that accesses to a range of "magic paths"
282potentially make your system access other hosts on your network. curl cannot
283protect you against this.
284
285# What if the user can set the URL
286
287Applications may find it tempting to let users set the URL that it can work
288on. That is probably fine, but opens up for mischief and trickery that you as
289an application author may want to address or take precautions against.
290
291If your curl-using script allow a custom URL do you also, perhaps
292unintentionally, allow the user to pass other options to the curl command line
293if creative use of special characters are applied?
294
295If the user can set the URL, the user can also specify the scheme part to
296other protocols that you did not intend for users to use and perhaps did not
297consider. curl supports over 20 different URL schemes. "http://" might be what
298you thought, "ftp://" or "imap://" might be what the user gives your
299application. Also, cross-protocol operations might be done by using a
300particular scheme in the URL but point to a server doing a different protocol
301on a non-standard port.
302
303Remedies:
304
305## Use --proto
306
307curl command lines can use *--proto* to limit what URL schemes it accepts
308
309## Use CURLOPT_PROTOCOLS
310
311libcurl programs can use CURLOPT_PROTOCOLS(3) to limit what URL schemes it accepts
312
313## consider not allowing the user to set the full URL
314
315Maybe just let the user provide data for parts of it? Or maybe filter input to
316only allow specific choices?
317
318# RFC 3986 vs WHATWG URL
319
320curl supports URLs mostly according to how they are defined in RFC 3986, and
321has done so since the beginning.
322
323Web browsers mostly adhere to the WHATWG URL Specification.
324
325This deviance makes some URLs copied between browsers (or returned over HTTP
326for redirection) and curl not work the same way. It can also cause problems if
327an application parses URLs differently from libcurl and makes different
328assumptions about a link. This can mislead users into getting the wrong thing,
329connecting to the wrong host or otherwise not working identically.
330
331Within an application, this can be mitigated by always using the
332curl_url(3) API to parse URLs, ensuring that they are parsed the same way
333as within libcurl itself.
334
335# FTP uses two connections
336
337When performing an FTP transfer, two TCP connections are used: one for setting
338up the transfer and one for the actual data.
339
340FTP is not only unauthenticated, but the setting up of the second transfer is
341also a weak spot. The second connection to use for data, is either setup with
342the PORT/EPRT command that makes the server connect back to the client on the
343given IP+PORT, or with PASV/EPSV that makes the server setup a port to listen
344to and tells the client to connect to a given IP+PORT.
345
346Again, unauthenticated means that the connection might be meddled with by a
347man-in-the-middle or that there is a malicious server pretending to be the
348right one.
349
350A malicious FTP server can respond to PASV commands with the IP+PORT of a
351totally different machine. Perhaps even a third party host, and when there are
352many clients trying to connect to that third party, it could create a
353Distributed Denial-Of-Service attack out of it. If the client makes an upload
354operation, it can make the client send the data to another site. If the
355attacker can affect what data the client uploads, it can be made to work as a
356HTTP request and then the client could be made to issue HTTP requests to third
357party hosts.
358
359An attacker that manages to control curl's command line options can tell curl
360to send an FTP PORT command to ask the server to connect to a third party host
361instead of back to curl.
362
363The fact that FTP uses two connections makes it vulnerable in a way that is
364hard to avoid.
365
366# Denial of Service
367
368A malicious server could cause libcurl to effectively hang by sending data
369slowly, or even no data at all but just keeping the TCP connection open. This
370could effectively result in a denial-of-service attack. The
371CURLOPT_TIMEOUT(3) and/or CURLOPT_LOW_SPEED_LIMIT(3) options can
372be used to mitigate against this.
373
374A malicious server could cause libcurl to download an infinite amount of data,
375potentially causing all of memory or disk to be filled. Setting the
376CURLOPT_MAXFILESIZE_LARGE(3) option is not sufficient to guard against
377this. Instead, applications should monitor the amount of data received within
378the write or progress callback and abort once the limit is reached.
379
380A malicious HTTP server could cause an infinite redirection loop, causing a
381denial-of-service. This can be mitigated by using the
382CURLOPT_MAXREDIRS(3) option.
383
384# Arbitrary Headers
385
386User-supplied data must be sanitized when used in options like
387CURLOPT_USERAGENT(3), CURLOPT_HTTPHEADER(3),
388CURLOPT_POSTFIELDS(3) and others that are used to generate structured
389data. Characters like embedded carriage returns or ampersands could allow the
390user to create additional headers or fields that could cause malicious
391transactions.
392
393# Server-supplied Names
394
395A server can supply data which the application may, in some cases, use as a
396filename. The curl command-line tool does this with *--remote-header-name*,
397using the Content-disposition: header to generate a filename. An application
398could also use CURLINFO_EFFECTIVE_URL(3) to generate a filename from a
399server-supplied redirect URL. Special care must be taken to sanitize such
400names to avoid the possibility of a malicious server supplying one like
401**"/etc/passwd"**, **"autoexec.bat"**, **"prn:"** or even **".bashrc"**.
402
403# Server Certificates
404
405A secure application should never use the CURLOPT_SSL_VERIFYPEER(3)
406option to disable certificate validation. There are numerous attacks that are
407enabled by applications that fail to properly validate server TLS/SSL
408certificates, thus enabling a malicious server to spoof a legitimate
409one. HTTPS without validated certificates is potentially as insecure as a
410plain HTTP connection.
411
412# Showing What You Do
413
414Relatedly, be aware that in situations when you have problems with libcurl and
415ask someone for help, everything you reveal in order to get best possible help
416might also impose certain security related risks. Host names, user names,
417paths, operating system specifics, etc. (not to mention passwords of course)
418may in fact be used by intruders to gain additional information of a potential
419target.
420
421Be sure to limit access to application logs if they could hold private or
422security-related data. Besides the obvious candidates like user names and
423passwords, things like URLs, cookies or even file names could also hold
424sensitive data.
425
426To avoid this problem, you must of course use your common sense. Often, you
427can just edit out the sensitive data or just search/replace your true
428information with faked data.
429
430# setuid applications using libcurl
431
432libcurl-using applications that set the 'setuid' bit to run with elevated or
433modified rights also implicitly give that extra power to libcurl and this
434should only be done after careful considerations.
435
436Giving setuid powers to the application means that libcurl can save files using
437those new rights (if for example the `SSLKEYLOGFILE` environment variable is
438set). Also: if the application wants these powers to read or manage secrets
439that the user is otherwise not able to view (like credentials for a login
440etc), it should be noted that libcurl still might understand proxy environment
441variables that allow the user to redirect libcurl operations to use a proxy
442controlled by the user.
443
444# File descriptors, fork and NTLM
445
446An application that uses libcurl and invokes *fork()* gets all file
447descriptors duplicated in the child process, including the ones libcurl
448created.
449
450libcurl itself uses *fork()* and *execl()* if told to use the
451**CURLAUTH_NTLM_WB** authentication method which then invokes the helper
452command in a child process with file descriptors duplicated. Make sure that
453only the trusted and reliable helper program is invoked!
454
455# Secrets in memory
456
457When applications pass user names, passwords or other sensitive data to
458libcurl to be used for upcoming transfers, those secrets are kept around as-is
459in memory. In many cases they are stored in the heap for as long as the handle
460itself for which the options are set.
461
462If an attacker can access the heap, like maybe by reading swap space or via a
463core dump file, such data might be accessible.
464
465Further, when eventually closing a handle and the secrets are no longer
466needed, libcurl does not explicitly clear memory before freeing it, so
467credentials may be left in freed data.
468
469# Saving files
470
471libcurl cannot protect against attacks where an attacker has write access to
472the same directory where libcurl is directed to save files.
473
474# Cookies
475
476If libcurl is built with PSL (**Public Suffix List**) support, it detects and
477discards cookies that are specified for such suffix domains that should not be
478allowed to have cookies.
479
480if libcurl is *not* built with PSL support, it has no ability to stop super
481cookies.
482
483# Report Security Problems
484
485Should you detect or just suspect a security problem in libcurl or curl,
486contact the project curl security team immediately. See
487https://curl.se/dev/secprocess.html for details.
488