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