quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

libcurl-security.md (22450B)


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