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