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