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