Return to libcurl-security.3 CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / docs / libcurl |
1.1 ! misho 1: .\" ************************************************************************** ! 2: .\" * _ _ ____ _ ! 3: .\" * Project ___| | | | _ \| | ! 4: .\" * / __| | | | |_) | | ! 5: .\" * | (__| |_| | _ <| |___ ! 6: .\" * \___|\___/|_| \_\_____| ! 7: .\" * ! 8: .\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. ! 9: .\" * ! 10: .\" * This software is licensed as described in the file COPYING, which ! 11: .\" * you should have received as part of this distribution. The terms ! 12: .\" * are also available at https://curl.haxx.se/docs/copyright.html. ! 13: .\" * ! 14: .\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell ! 15: .\" * copies of the Software, and permit persons to whom the Software is ! 16: .\" * furnished to do so, under the terms of the COPYING file. ! 17: .\" * ! 18: .\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY ! 19: .\" * KIND, either express or implied. ! 20: .\" * ! 21: .\" ************************************************************************** ! 22: .\" ! 23: .TH libcurl-security 3 "March 09, 2020" "libcurl 7.70.0" "libcurl security" ! 24: ! 25: .SH NAME ! 26: libcurl-security \- security considerations when using libcurl ! 27: .SH "Security" ! 28: The libcurl project takes security seriously. The library is written with ! 29: caution and precautions are taken to mitigate many kinds of risks encountered ! 30: while operating with potentially malicious servers on the Internet. It is a ! 31: powerful library, however, which allows application writers to make trade-offs ! 32: between ease of writing and exposure to potential risky operations. If used ! 33: the right way, you can use libcurl to transfer data pretty safely. ! 34: ! 35: Many applications are used in closed networks where users and servers can ! 36: (possibly) be trusted, but many others are used on arbitrary servers and are ! 37: fed input from potentially untrusted users. Following is a discussion about ! 38: some risks in the ways in which applications commonly use libcurl and ! 39: potential mitigations of those risks. It is by no means comprehensive, but ! 40: shows classes of attacks that robust applications should consider. The Common ! 41: Weakness Enumeration project at https://cwe.mitre.org/ is a good reference for ! 42: many of these and similar types of weaknesses of which application writers ! 43: should be aware. ! 44: .SH "Command Lines" ! 45: If you use a command line tool (such as curl) that uses libcurl, and you give ! 46: options to the tool on the command line those options can very likely get read ! 47: by other users of your system when they use 'ps' or other tools to list ! 48: currently running processes. ! 49: ! 50: To avoid these problems, never feed sensitive things to programs using command ! 51: line options. Write them to a protected file and use the \-K option to avoid ! 52: this. ! 53: .SH ".netrc" ! 54: \&.netrc is a pretty handy file/feature that allows you to login quickly and ! 55: automatically to frequently visited sites. The file contains passwords in ! 56: clear text and is a real security risk. In some cases, your .netrc is also ! 57: stored in a home directory that is NFS mounted or used on another network ! 58: based file system, so the clear text password will fly through your network ! 59: every time anyone reads that file! ! 60: ! 61: For applications that enable .netrc use, a user who manage to set the right ! 62: URL might then be possible to pass on passwords. ! 63: ! 64: To avoid these problems, don't use .netrc files and never store passwords in ! 65: plain text anywhere. ! 66: .SH "Clear Text Passwords" ! 67: Many of the protocols libcurl supports send name and password unencrypted as ! 68: clear text (HTTP Basic authentication, FTP, TELNET etc). It is very easy for ! 69: anyone on your network or a network nearby yours to just fire up a network ! 70: analyzer tool and eavesdrop on your passwords. Don't let the fact that HTTP ! 71: Basic uses base64 encoded passwords fool you. They may not look readable at a ! 72: first glance, but they very easily "deciphered" by anyone within seconds. ! 73: ! 74: To avoid this problem, use an authentication mechanism or other protocol that ! 75: doesn't let snoopers see your password: Digest, CRAM-MD5, Kerberos, SPNEGO or ! 76: NTLM authentication. Or even better: use authenticated protocols that protect ! 77: the entire connection and everything sent over it. ! 78: .SH "Un-authenticated Connections" ! 79: Protocols that don't 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 host name, it is not safe ! 83: as long as the connection is un-authenticated. There can be a ! 84: man-in-the-middle or in fact the whole server might have been replaced by an ! 85: evil actor. ! 86: ! 87: Un-authenticated protocols are unsafe. The data that comes back to curl may ! 88: have been injected by an attacker. The data that curl sends might be modified ! 89: before it reaches the intended server. If it even reaches the intended server ! 90: at all. ! 91: ! 92: Remedies: ! 93: .IP "Restrict operations to authenticated transfers" ! 94: Ie use authenticated protocols protected with HTTPS or SSH. ! 95: .IP "Make sure the server's certificate etc is verified" ! 96: Never ever switch off certificate verification. ! 97: .SH "Redirects" ! 98: The \fICURLOPT_FOLLOWLOCATION(3)\fP option automatically follows HTTP ! 99: redirects sent by a remote server. These redirects can refer to any kind of ! 100: URL, not just HTTP. libcurl restricts the protocols allowed to be used in ! 101: redirects for security reasons: only HTTP, HTTPS, FTP and FTPS are ! 102: enabled by default. Applications may opt to restrict that set further. ! 103: ! 104: A redirect to a file: URL would cause the libcurl to read (or write) arbitrary ! 105: files from the local filesystem. If the application returns the data back to ! 106: the user (as would happen in some kinds of CGI scripts), an attacker could ! 107: leverage this to read otherwise forbidden data (e.g. ! 108: file://localhost/etc/passwd). ! 109: ! 110: If authentication credentials are stored in the ~/.netrc file, or Kerberos ! 111: is in use, any other URL type (not just file:) that requires ! 112: authentication is also at risk. A redirect such as ! 113: ftp://some-internal-server/private-file would then return data even when ! 114: the server is password protected. ! 115: ! 116: In the same way, if an unencrypted SSH private key has been configured for the ! 117: user running the libcurl application, SCP: or SFTP: URLs could access password ! 118: or private-key protected resources, ! 119: e.g. sftp://user@some-internal-server/etc/passwd ! 120: ! 121: The \fICURLOPT_REDIR_PROTOCOLS(3)\fP and \fICURLOPT_NETRC(3)\fP options can be ! 122: used to mitigate against this kind of attack. ! 123: ! 124: A redirect can also specify a location available only on the machine running ! 125: libcurl, including servers hidden behind a firewall from the attacker. ! 126: e.g. http://127.0.0.1/ or http://intranet/delete-stuff.cgi?delete=all or ! 127: tftp://bootp-server/pc-config-data ! 128: ! 129: Applications can mitigate against this by disabling ! 130: \fICURLOPT_FOLLOWLOCATION(3)\fP and handling redirects itself, sanitizing URLs ! 131: as necessary. Alternately, an app could leave \fICURLOPT_FOLLOWLOCATION(3)\fP ! 132: enabled but set \fICURLOPT_REDIR_PROTOCOLS(3)\fP and install a ! 133: \fICURLOPT_OPENSOCKETFUNCTION(3)\fP callback function in which addresses are ! 134: sanitized before use. ! 135: .SH "Local Resources" ! 136: A user who can control the DNS server of a domain being passed in within a URL ! 137: can change the address of the host to a local, private address which a ! 138: server-side libcurl-using application could then use. e.g. the innocuous URL ! 139: http://fuzzybunnies.example.com/ could actually resolve to the IP address of a ! 140: server behind a firewall, such as 127.0.0.1 or 10.1.2.3. Applications can ! 141: mitigate against this by setting a \fICURLOPT_OPENSOCKETFUNCTION(3)\fP and ! 142: checking the address before a connection. ! 143: ! 144: All the malicious scenarios regarding redirected URLs apply just as well to ! 145: non-redirected URLs, if the user is allowed to specify an arbitrary URL that ! 146: could point to a private resource. For example, a web app providing a ! 147: translation service might happily translate file://localhost/etc/passwd and ! 148: display the result. Applications can mitigate against this with the ! 149: \fICURLOPT_PROTOCOLS(3)\fP option as well as by similar mitigation techniques ! 150: for redirections. ! 151: ! 152: A malicious FTP server could in response to the PASV command return an IP ! 153: address and port number for a server local to the app running libcurl but ! 154: behind a firewall. Applications can mitigate against this by using the ! 155: \fICURLOPT_FTP_SKIP_PASV_IP(3)\fP option or \fICURLOPT_FTPPORT(3)\fP. ! 156: ! 157: Local servers sometimes assume local access comes from friends and trusted ! 158: users. An application that expects http://example.com/file_to_read that and ! 159: instead gets http://192.168.0.1/my_router_config might print a file that would ! 160: otherwise be protected by the firewall. ! 161: ! 162: Allowing your application to connect to local hosts, be it the same machine ! 163: that runs the application or a machine on the same local network, might be ! 164: possible to exploit by an attacker who then perhaps can "port-scan" the ! 165: particular hosts - depending on how the application and servers acts. ! 166: .SH "IPv6 Addresses" ! 167: libcurl will normally handle IPv6 addresses transparently and just as easily ! 168: as IPv4 addresses. That means that a sanitizing function that filters out ! 169: addresses like 127.0.0.1 isn't sufficient--the equivalent IPv6 addresses ::1, ! 170: ::, 0:00::0:1, ::127.0.0.1 and ::ffff:7f00:1 supplied somehow by an attacker ! 171: would all bypass a naive filter and could allow access to undesired local ! 172: resources. IPv6 also has special address blocks like link-local and ! 173: site-local that generally shouldn't be accessed by a server-side libcurl-using ! 174: application. A poorly-configured firewall installed in a data center, ! 175: organization or server may also be configured to limit IPv4 connections but ! 176: leave IPv6 connections wide open. In some cases, setting ! 177: \fICURLOPT_IPRESOLVE(3)\fP to CURL_IPRESOLVE_V4 can be used to limit resolved ! 178: addresses to IPv4 only and bypass these issues. ! 179: .SH Uploads ! 180: When uploading, a redirect can cause a local (or remote) file to be ! 181: overwritten. Applications must not allow any unsanitized URL to be passed in ! 182: for uploads. Also, \fICURLOPT_FOLLOWLOCATION(3)\fP should not be used on ! 183: uploads. Instead, the applications should consider handling redirects itself, ! 184: sanitizing each URL first. ! 185: .SH Authentication ! 186: Use of \fICURLOPT_UNRESTRICTED_AUTH(3)\fP could cause authentication ! 187: information to be sent to an unknown second server. Applications can mitigate ! 188: against this by disabling \fICURLOPT_FOLLOWLOCATION(3)\fP and handling ! 189: redirects itself, sanitizing where necessary. ! 190: ! 191: Use of the CURLAUTH_ANY option to \fICURLOPT_HTTPAUTH(3)\fP could result in ! 192: user name and password being sent in clear text to an HTTP server. Instead, ! 193: use CURLAUTH_ANYSAFE which ensures that the password is encrypted over the ! 194: network, or else fail the request. ! 195: ! 196: Use of the CURLUSESSL_TRY option to \fICURLOPT_USE_SSL(3)\fP could result in ! 197: user name and password being sent in clear text to an FTP server. Instead, ! 198: use CURLUSESSL_CONTROL to ensure that an encrypted connection is used or else ! 199: fail the request. ! 200: .SH Cookies ! 201: If cookies are enabled and cached, then a user could craft a URL which ! 202: performs some malicious action to a site whose authentication is already ! 203: stored in a cookie. e.g. http://mail.example.com/delete-stuff.cgi?delete=all ! 204: Applications can mitigate against this by disabling cookies or clearing them ! 205: between requests. ! 206: .SH "Dangerous SCP URLs" ! 207: SCP URLs can contain raw commands within the scp: URL, which is a side effect ! 208: of how the SCP protocol is designed. e.g. ! 209: ! 210: scp://user:pass@host/a;date >/tmp/test; ! 211: ! 212: Applications must not allow unsanitized SCP: URLs to be passed in for ! 213: downloads. ! 214: .SH "file://" ! 215: By default curl and libcurl support file:// URLs. Such a URL is always an ! 216: access, or attempted access, to a local resource. If your application wants to ! 217: avoid that, keep control of what URLs to use and/or prevent curl/libcurl from ! 218: using the protocol. ! 219: ! 220: By default, libcurl prohibits redirects to file:// URLs. ! 221: ! 222: .SH "Warning: file:// on Windows" ! 223: The Windows operating system will automatically, and without any way for ! 224: applications to disable it, try to establish a connection to another host over ! 225: the network and access it (over SMB or other protocols), if only the correct ! 226: file path is accessed. ! 227: ! 228: When first realizing this, the curl team tried to filter out such attempts in ! 229: order to protect applications for inadvertent probes of for example internal ! 230: networks etc. This resulted in CVE-2019-15601 and the associated security fix. ! 231: ! 232: However, we've since been made aware of the fact that the previous fix was far ! 233: from adequate as there are several other ways to accomplish more or less the ! 234: same thing: accessing a remote host over the network instead of the local file ! 235: system. ! 236: ! 237: The conclusion we have come to is that this is a weakness or feature in the ! 238: Windows operating system itself, that we as an application cannot safely ! 239: protect users against. It would just be a whack-a-mole race we don't want to ! 240: participate in. There are too many ways to do it and there's no knob we can ! 241: use to turn off the practice. ! 242: ! 243: If you use curl or libcurl on Windows (any version), disable the use of the ! 244: FILE protocol in curl or be prepared that accesses to a range of "magic paths" ! 245: will potentially make your system try to access other hosts on your ! 246: network. curl cannot protect you against this. ! 247: .SH "What if the user can set the URL" ! 248: Applications may find it tempting to let users set the URL that it can work ! 249: on. That's probably fine, but opens up for mischief and trickery that you as ! 250: an application author may want to address or take precautions against. ! 251: ! 252: If your curl-using script allow a custom URL do you also, perhaps ! 253: unintentionally, allow the user to pass other options to the curl command line ! 254: if creative use of special characters are applied? ! 255: ! 256: If the user can set the URL, the user can also specify the scheme part to ! 257: other protocols that you didn't intend for users to use and perhaps didn't ! 258: consider. curl supports over 20 different URL schemes. "http://" might be what ! 259: you thought, "ftp://" or "imap://" might be what the user gives your ! 260: application. Also, cross-protocol operations might be done by using a ! 261: particular scheme in the URL but point to a server doing a different protocol ! 262: on a non-standard port. ! 263: ! 264: Remedies: ! 265: .IP "Use --proto" ! 266: curl command lines can use \fI--proto\fP to limit what URL schemes it accepts ! 267: .IP "Use CURLOPT_PROTOCOLS" ! 268: libcurl programs can use \fICURLOPT_PROTOCOLS(3)\fP to limit what URL schemes it accepts ! 269: .IP "consider not allowing the user to set the full URL" ! 270: Maybe just let the user provide data for parts of it? Or maybe filter input to ! 271: only allow specific choices? ! 272: .SH "RFC 3986 vs WHATWG URL" ! 273: curl supports URLs mostly according to how they are defined in RFC 3986, and ! 274: has done so since the beginning. ! 275: ! 276: Web browsers mostly adhere to the WHATWG URL Specification. ! 277: ! 278: This deviance makes some URLs copied between browsers (or returned over HTTP ! 279: for redirection) and curl not work the same way. This can mislead users into ! 280: getting the wrong thing, connecting to the wrong host or otherwise not work ! 281: identically. ! 282: .SH "FTP uses two connections" ! 283: When performing an FTP transfer, two TCP connections are used: one for setting ! 284: up the transfer and one for the actual data. ! 285: ! 286: FTP is not only un-authenticated, but the setting up of the second transfer is ! 287: also a weak spot. The second connection to use for data, is either setup with ! 288: the PORT/EPRT command that makes the server connect back to the client on the ! 289: given IP+PORT, or with PASV/EPSV that makes the server setup a port to listen ! 290: to and tells the client to connect to a given IP+PORT. ! 291: ! 292: Again, un-authenticated means that the connection might be meddled with by a ! 293: man-in-the-middle or that there's a malicious server pretending to be the ! 294: right one. ! 295: ! 296: A malicious FTP server can respond to PASV commands with the IP+PORT of a ! 297: totally different machine. Perhaps even a third party host, and when there are ! 298: many clients trying to connect to that third party, it could create a ! 299: Distributed Denial-Of-Service attack out of it! If the client makes an upload ! 300: operation, it can make the client send the data to another site. If the ! 301: attacker can affect what data the client uploads, it can be made to work as a ! 302: HTTP request and then the client could be made to issue HTTP requests to third ! 303: party hosts. ! 304: ! 305: An attacker that manages to control curl's command line options can tell curl ! 306: to send an FTP PORT command to ask the server to connect to a third party host ! 307: instead of back to curl. ! 308: ! 309: The fact that FTP uses two connections makes it vulnerable in a way that is ! 310: hard to avoid. ! 311: .SH "Denial of Service" ! 312: A malicious server could cause libcurl to effectively hang by sending data ! 313: very slowly, or even no data at all but just keeping the TCP connection open. ! 314: This could effectively result in a denial-of-service attack. The ! 315: \fICURLOPT_TIMEOUT(3)\fP and/or \fICURLOPT_LOW_SPEED_LIMIT(3)\fP options can ! 316: be used to mitigate against this. ! 317: ! 318: A malicious server could cause libcurl to download an infinite amount of data, ! 319: potentially causing all of memory or disk to be filled. Setting the ! 320: \fICURLOPT_MAXFILESIZE_LARGE(3)\fP option is not sufficient to guard against ! 321: this. Instead, applications should monitor the amount of data received within ! 322: the write or progress callback and abort once the limit is reached. ! 323: ! 324: A malicious HTTP server could cause an infinite redirection loop, causing a ! 325: denial-of-service. This can be mitigated by using the ! 326: \fICURLOPT_MAXREDIRS(3)\fP option. ! 327: .SH "Arbitrary Headers" ! 328: User-supplied data must be sanitized when used in options like ! 329: \fICURLOPT_USERAGENT(3)\fP, \fICURLOPT_HTTPHEADER(3)\fP, ! 330: \fICURLOPT_POSTFIELDS(3)\fP and others that are used to generate structured ! 331: data. Characters like embedded carriage returns or ampersands could allow the ! 332: user to create additional headers or fields that could cause malicious ! 333: transactions. ! 334: .SH "Server-supplied Names" ! 335: A server can supply data which the application may, in some cases, use as a ! 336: file name. The curl command-line tool does this with ! 337: \fI--remote-header-name\fP, using the Content-disposition: header to generate ! 338: a file name. An application could also use \fICURLINFO_EFFECTIVE_URL(3)\fP to ! 339: generate a file name from a server-supplied redirect URL. Special care must be ! 340: taken to sanitize such names to avoid the possibility of a malicious server ! 341: supplying one like "/etc/passwd", "\\autoexec.bat", "prn:" or even ".bashrc". ! 342: .SH "Server Certificates" ! 343: A secure application should never use the \fICURLOPT_SSL_VERIFYPEER(3)\fP ! 344: option to disable certificate validation. There are numerous attacks that are ! 345: enabled by applications that fail to properly validate server TLS/SSL ! 346: certificates, thus enabling a malicious server to spoof a legitimate ! 347: one. HTTPS without validated certificates is potentially as insecure as a ! 348: plain HTTP connection. ! 349: .SH "Report Security Problems" ! 350: Should you detect or just suspect a security problem in libcurl or curl, ! 351: contact the project curl security team immediately. See ! 352: https://curl.haxx.se/dev/secprocess.html for details. ! 353: .SH "Showing What You Do" ! 354: Relatedly, be aware that in situations when you have problems with libcurl and ! 355: ask someone for help, everything you reveal in order to get best possible help ! 356: might also impose certain security related risks. Host names, user names, ! 357: paths, operating system specifics, etc. (not to mention passwords of course) ! 358: may in fact be used by intruders to gain additional information of a potential ! 359: target. ! 360: ! 361: Be sure to limit access to application logs if they could hold private or ! 362: security-related data. Besides the obvious candidates like user names and ! 363: passwords, things like URLs, cookies or even file names could also hold ! 364: sensitive data. ! 365: ! 366: To avoid this problem, you must of course use your common sense. Often, you ! 367: can just edit out the sensitive data or just search/replace your true ! 368: information with faked data.