| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- .\" generated by cd2nroff 0.1 from libcurl-security.md
- .TH libcurl-security 3 "2025-01-17" libcurl
- .SH NAME
- libcurl\-security \- security considerations when using libcurl
- .SH Security
- The libcurl project takes security seriously. The library is written with
- caution and precautions are taken to mitigate many kinds of risks encountered
- while operating with potentially malicious servers on the Internet. It is a
- powerful library, however, which allows application writers to make trade\-offs
- between ease of writing and exposure to potential risky operations. If used
- the right way, you can use libcurl to transfer data pretty safely.
- Many applications are used in closed networks where users and servers can
- (possibly) be trusted, but many others are used on arbitrary servers and are
- fed input from potentially untrusted users. Following is a discussion about
- some risks in the ways in which applications commonly use libcurl and
- potential mitigations of those risks. It is not comprehensive, but shows
- classes of attacks that robust applications should consider. The Common
- Weakness Enumeration project at https://cwe.mitre.org/ is a good reference for
- many of these and similar types of weaknesses of which application writers
- should be aware.
- .SH Command Lines
- If you use a command line tool (such as curl) that uses libcurl, and you give
- options to the tool on the command line those options can get read by other
- users of your system when they use \fIps\fP or other tools to list currently
- running processes.
- To avoid these problems, never feed sensitive things to programs using command
- line options. Write them to a protected file and use the \-K option to avoid
- this.
- .SH .netrc
- \&.netrc is a pretty handy file/feature that allows you to login quickly and
- automatically to frequently visited sites. The file contains passwords in
- clear text and is a real security risk. In some cases, your .netrc is also
- stored in a home directory that is NFS mounted or used on another network
- based file system, so the clear text password flies through your network every
- time anyone reads that file.
- For applications that enable .netrc use, a user who manage to set the right
- URL might then be possible to pass on passwords.
- To avoid these problems, do not use .netrc files and never store passwords in
- plain text anywhere.
- .SH Clear Text Passwords
- Many of the protocols libcurl supports send name and password unencrypted as
- clear text (HTTP Basic authentication, FTP, TELNET etc). It is easy for anyone
- on your network or a network nearby yours to just fire up a network analyzer
- tool and eavesdrop on your passwords. Do not let the fact that HTTP Basic uses
- base64 encoded passwords fool you. They may not look readable at a first
- glance, but they are easily "deciphered" by anyone within seconds.
- To avoid this problem, use an authentication mechanism or other protocol that
- does not let snoopers see your password: Digest, CRAM\-MD5, Kerberos, SPNEGO or
- NTLM authentication. Or even better: use authenticated protocols that protect
- the entire connection and everything sent over it.
- .SH Unauthenticated Connections
- Protocols that do not have any form of cryptographic authentication cannot
- with any certainty know that they communicate with the right remote server.
- If your application is using a fixed scheme or fixed hostname, it is not safe
- as long as the connection is unauthenticated. There can be a man\-in\-the\-middle
- or in fact the whole server might have been replaced by an evil actor.
- Unauthenticated protocols are unsafe. The data that comes back to curl may
- have been injected by an attacker. The data that curl sends might be modified
- before it reaches the intended server. If it even reaches the intended server
- at all.
- Remedies:
- .IP "Restrict operations to authenticated transfers"
- Use authenticated protocols protected with HTTPS or SSH.
- .IP "Make sure the server's certificate etc is verified"
- Never ever switch off certificate verification.
- .SH Redirects
- The \fICURLOPT_FOLLOWLOCATION(3)\fP option automatically follows HTTP
- redirects sent by a remote server. These redirects can refer to any kind of
- URL, not just HTTP. libcurl restricts the protocols allowed to be used in
- redirects for security reasons: only HTTP, HTTPS, FTP and FTPS are
- enabled by default. Applications may opt to restrict that set further.
- A redirect to a file: URL would cause the libcurl to read (or write) arbitrary
- files from the local filesystem. If the application returns the data back to
- the user (as would happen in some kinds of CGI scripts), an attacker could
- leverage this to read otherwise forbidden data (e.g.
- \fBfile://localhost/etc/passwd\fP).
- If authentication credentials are stored in the ~/.netrc file, or Kerberos is
- in use, any other URL type (not just file:) that requires authentication is
- also at risk. A redirect such as \fBftp://some\-internal\-server/private\-file\fP would
- then return data even when the server is password protected.
- In the same way, if an unencrypted SSH private key has been configured for the
- user running the libcurl application, SCP: or SFTP: URLs could access password
- or private\-key protected resources,
- e.g. \fBsftp://user@some\-internal\-server/etc/passwd\fP
- The \fICURLOPT_REDIR_PROTOCOLS_STR(3)\fP and \fICURLOPT_NETRC(3)\fP options can be
- used to mitigate against this kind of attack.
- A redirect can also specify a location available only on the machine running
- libcurl, including servers hidden behind a firewall from the attacker.
- E.g. \fBhttp://127.0.0.1/\fP or \fBhttp://intranet/delete\-stuff.cgi?delete=all\fP or
- \fBtftp://bootp\-server/pc\-config\-data\fP
- Applications can mitigate against this by disabling
- \fICURLOPT_FOLLOWLOCATION(3)\fP and handling redirects itself, sanitizing URLs
- as necessary. Alternately, an app could leave \fICURLOPT_FOLLOWLOCATION(3)\fP
- enabled but set \fICURLOPT_REDIR_PROTOCOLS_STR(3)\fP and install a
- \fICURLOPT_OPENSOCKETFUNCTION(3)\fP or \fICURLOPT_PREREQFUNCTION(3)\fP callback
- function in which addresses are sanitized before use.
- .SH CRLF in Headers
- For all options in libcurl which specify headers, including but not limited to
- \fICURLOPT_HTTPHEADER(3)\fP, \fICURLOPT_PROXYHEADER(3)\fP,
- \fICURLOPT_COOKIE(3)\fP, \fICURLOPT_USERAGENT(3)\fP, \fICURLOPT_REFERER(3)\fP
- and \fICURLOPT_RANGE(3)\fP, libcurl sends the headers as\-is and does not apply
- any special sanitation or normalization to them.
- If you allow untrusted user input into these options without sanitizing CRLF
- sequences in them, someone malicious may be able to modify the request in a
- way you did not intend such as injecting new headers.
- .SH Local Resources
- A user who can control the DNS server of a domain being passed in within a URL
- can change the address of the host to a local, private address which a
- server\-side libcurl\-using application could then use. E.g. the innocuous URL
- \fBhttp://fuzzybunnies.example.com/\fP could actually resolve to the IP
- address of a server behind a firewall, such as 127.0.0.1 or
- 10.1.2.3. Applications can mitigate against this by setting a
- \fICURLOPT_OPENSOCKETFUNCTION(3)\fP or \fICURLOPT_PREREQFUNCTION(3)\fP and
- checking the address before a connection.
- All the malicious scenarios regarding redirected URLs apply just as well to
- non\-redirected URLs, if the user is allowed to specify an arbitrary URL that
- could point to a private resource. For example, a web app providing a
- translation service might happily translate \fBfile://localhost/etc/passwd\fP
- and display the result. Applications can mitigate against this with the
- \fICURLOPT_PROTOCOLS_STR(3)\fP option as well as by similar mitigation techniques
- for redirections.
- A malicious FTP server could in response to the PASV command return an IP
- address and port number for a server local to the app running libcurl but
- behind a firewall. Applications can mitigate against this by using the
- \fICURLOPT_FTP_SKIP_PASV_IP(3)\fP option or \fICURLOPT_FTPPORT(3)\fP.
- Local servers sometimes assume local access comes from friends and trusted
- users. An application that expects https://example.com/file_to_read that and
- instead gets http://192.168.0.1/my_router_config might print a file that would
- otherwise be protected by the firewall.
- Allowing your application to connect to local hosts, be it the same machine
- that runs the application or a machine on the same local network, might be
- possible to exploit by an attacker who then perhaps can "port\-scan" the
- particular hosts \- depending on how the application and servers acts.
- .SH IPv4 Addresses
- Some users might be tempted to filter access to local resources or similar
- based on numerical IPv4 addresses used in URLs. This is a bad and error\-prone
- idea because of the many different ways a numerical IPv4 address can be
- specified and libcurl accepts: one to four dot\-separated fields using one of
- or a mix of decimal, octal or hexadecimal encoding.
- .SH IPv6 Addresses
- libcurl handles IPv6 addresses transparently and just as easily as IPv4
- addresses. That means that a sanitizing function that filters out addresses
- like 127.0.0.1 is not sufficient \- the equivalent IPv6 addresses \fB::1\fP,
- \fB::\fP, \fB0:00::0:1\fP, \fB::127.0.0.1\fP and \fB::ffff:7f00:1\fP supplied
- somehow by an attacker would all bypass a naive filter and could allow access
- to undesired local resources. IPv6 also has special address blocks like
- link\-local and site\-local that generally should not be accessed by a
- server\-side libcurl\-using application. A poorly configured firewall installed
- in a data center, organization or server may also be configured to limit IPv4
- connections but leave IPv6 connections wide open. In some cases, setting
- \fICURLOPT_IPRESOLVE(3)\fP to CURL_IPRESOLVE_V4 can be used to limit resolved
- addresses to IPv4 only and bypass these issues.
- .SH Uploads
- When uploading, a redirect can cause a local (or remote) file to be
- overwritten. Applications must not allow any unsanitized URL to be passed in
- for uploads. Also, \fICURLOPT_FOLLOWLOCATION(3)\fP should not be used on
- uploads. Instead, the applications should consider handling redirects itself,
- sanitizing each URL first.
- .SH Authentication
- Use of \fICURLOPT_UNRESTRICTED_AUTH(3)\fP could cause authentication
- information to be sent to an unknown second server. Applications can mitigate
- against this by disabling \fICURLOPT_FOLLOWLOCATION(3)\fP and handling
- redirects itself, sanitizing where necessary.
- Use of the CURLAUTH_ANY option to \fICURLOPT_HTTPAUTH(3)\fP could result in username
- and password being sent in clear text to an HTTP server. Instead, use
- CURLAUTH_ANYSAFE which ensures that the password is encrypted over the
- network, or else fail the request.
- Use of the CURLUSESSL_TRY option to \fICURLOPT_USE_SSL(3)\fP could result in
- username and password being sent in clear text to an FTP server. Instead, use
- CURLUSESSL_CONTROL to ensure that an encrypted connection is used or else fail
- the request.
- .SH Cookies
- If cookies are enabled and cached, then a user could craft a URL which
- performs some malicious action to a site whose authentication is already
- stored in a cookie. E.g.
- \fBhttp://mail.example.com/delete\-stuff.cgi?delete=all\fP Applications can
- mitigate against this by disabling cookies or clearing them between requests.
- .SH Dangerous SCP URLs
- SCP URLs can contain raw commands within the scp: URL, which is a side effect
- of how the SCP protocol is designed. E.g.
- .nf
- scp://user:pass@host/a;date >/tmp/test;
- .fi
- Applications must not allow unsanitized SCP: URLs to be passed in for
- downloads.
- .SH file://
- By default curl and libcurl support file:// URLs. Such a URL is always an
- access, or attempted access, to a local resource. If your application wants to
- avoid that, keep control of what URLs to use and/or prevent curl/libcurl from
- using the protocol.
- By default, libcurl prohibits redirects to file:// URLs.
- .SH Warning: file:// on Windows
- The Windows operating system tries automatically, and without any way for
- applications to disable it, to establish a connection to another host over the
- network and access it (over SMB or other protocols), if only the correct file
- path is accessed.
- When first realizing this, the curl team tried to filter out such attempts in
- order to protect applications for inadvertent probes of for example internal
- networks etc. This resulted in CVE\-2019\-15601 and the associated security fix.
- However, we have since been made aware of the fact that the previous fix was far
- from adequate as there are several other ways to accomplish more or less the
- same thing: accessing a remote host over the network instead of the local file
- system.
- The conclusion we have come to is that this is a weakness or feature in the
- Windows operating system itself, that we as an application cannot safely
- protect users against. It would just be a whack\-a\-mole race we do not want to
- participate in. There are too many ways to do it and there is no knob we can
- use to turn off the practice.
- If you use curl or libcurl on Windows (any version), disable the use of the
- FILE protocol in curl or be prepared that accesses to a range of "magic paths"
- potentially make your system access other hosts on your network. curl cannot
- protect you against this.
- .SH What if the user can set the URL
- Applications may find it tempting to let users set the URL that it can work
- on. That is probably fine, but opens up for mischief and trickery that you as
- an application author may want to address or take precautions against.
- If your curl\-using script allow a custom URL do you also, perhaps
- unintentionally, allow the user to pass other options to the curl command line
- if creative use of special characters are applied?
- If the user can set the URL, the user can also specify the scheme part to
- other protocols that you did not intend for users to use and perhaps did not
- consider. curl supports over 20 different URL schemes. "http://" might be what
- you thought, "ftp://" or "imap://" might be what the user gives your
- application. Also, cross\-protocol operations might be done by using a
- particular scheme in the URL but point to a server doing a different protocol
- on a non\-standard port.
- Remedies:
- .IP "Use --proto"
- curl command lines can use \fI\--proto\fP to limit what URL schemes it accepts
- .IP "Use CURLOPT_PROTOCOLS_STR"
- libcurl programs can use \fICURLOPT_PROTOCOLS_STR(3)\fP to limit what URL schemes it accepts
- .IP "consider not allowing the user to set the full URL"
- Maybe just let the user provide data for parts of it? Or maybe filter input to
- only allow specific choices?
- .SH RFC 3986 vs WHATWG URL
- curl supports URLs mostly according to how they are defined in RFC 3986, and
- has done so since the beginning.
- Web browsers mostly adhere to the WHATWG URL Specification.
- This deviance makes some URLs copied between browsers (or returned over HTTP
- for redirection) and curl not work the same way. It can also cause problems if
- an application parses URLs differently from libcurl and makes different
- assumptions about a link. This can mislead users into getting the wrong thing,
- connecting to the wrong host or otherwise not working identically.
- Within an application, this can be mitigated by always using the
- \fIcurl_url(3)\fP API to parse URLs, ensuring that they are parsed the same way
- as within libcurl itself.
- .SH FTP uses two connections
- When performing an FTP transfer, two TCP connections are used: one for setting
- up the transfer and one for the actual data.
- FTP is not only unauthenticated, but the setting up of the second transfer is
- also a weak spot. The second connection to use for data, is either setup with
- the PORT/EPRT command that makes the server connect back to the client on the
- given IP+PORT, or with PASV/EPSV that makes the server setup a port to listen
- to and tells the client to connect to a given IP+PORT.
- Again, unauthenticated means that the connection might be meddled with by a
- man\-in\-the\-middle or that there is a malicious server pretending to be the
- right one.
- A malicious FTP server can respond to PASV commands with the IP+PORT of a
- totally different machine. Perhaps even a third party host, and when there are
- many clients trying to connect to that third party, it could create a
- Distributed Denial\-Of\-Service attack out of it. If the client makes an upload
- operation, it can make the client send the data to another site. If the
- attacker can affect what data the client uploads, it can be made to work as a
- HTTP request and then the client could be made to issue HTTP requests to third
- party hosts.
- An attacker that manages to control curl\(aqs command line options can tell curl
- to send an FTP PORT command to ask the server to connect to a third party host
- instead of back to curl.
- The fact that FTP uses two connections makes it vulnerable in a way that is
- hard to avoid.
- .SH Active FTP passes on the local IP address
- If you use curl/libcurl to do \fIactive\fP FTP transfers, curl passes on the
- address of your local IP to the remote server \- even when for example using a
- SOCKS or HTTP proxy in between curl and the target server.
- .SH Denial of Service
- A malicious server could cause libcurl to effectively hang by sending data
- slowly, or even no data at all but just keeping the TCP connection open. This
- could effectively result in a denial\-of\-service attack. The
- \fICURLOPT_TIMEOUT(3)\fP and/or \fICURLOPT_LOW_SPEED_LIMIT(3)\fP options can
- be used to mitigate against this.
- A malicious server could cause libcurl to download an infinite amount of data,
- potentially causing system resources to be exhausted resulting in a system or
- application crash. Setting the \fICURLOPT_MAXFILESIZE_LARGE(3)\fP option is not
- sufficient to guard against this. Instead, applications should monitor the
- amount of data received within the write or progress callback and abort once
- the limit is reached.
- A malicious HTTP server could cause an infinite redirection loop, causing a
- denial\-of\-service. This can be mitigated by using the
- \fICURLOPT_MAXREDIRS(3)\fP option.
- .SH Arbitrary Headers
- User\-supplied data must be sanitized when used in options like
- \fICURLOPT_USERAGENT(3)\fP, \fICURLOPT_HTTPHEADER(3)\fP,
- \fICURLOPT_POSTFIELDS(3)\fP and others that are used to generate structured
- data. Characters like embedded carriage returns or ampersands could allow the
- user to create additional headers or fields that could cause malicious
- transactions.
- .SH Server-supplied Names
- A server can supply data which the application may, in some cases, use as a
- filename. The curl command\-line tool does this with \fI\--remote\-header\-name\fP,
- using the Content\-disposition: header to generate a filename. An application
- could also use \fICURLINFO_EFFECTIVE_URL(3)\fP to generate a filename from a
- server\-supplied redirect URL. Special care must be taken to sanitize such
- names to avoid the possibility of a malicious server supplying one like
- \fB"/etc/passwd"\fP, \fB"autoexec.bat"\fP, \fB"prn:"\fP or even \fB".bashrc"\fP.
- .SH Server Certificates
- A secure application should never use the \fICURLOPT_SSL_VERIFYPEER(3)\fP
- option to disable certificate validation. There are numerous attacks that are
- enabled by applications that fail to properly validate server TLS/SSL
- certificates, thus enabling a malicious server to spoof a legitimate
- one. HTTPS without validated certificates is potentially as insecure as a
- plain HTTP connection.
- .SH Showing What You Do
- Relatedly, be aware that in situations when you have problems with libcurl and
- ask someone for help, everything you reveal in order to get best possible help
- might also impose certain security related risks. Hostnames, usernames, paths,
- operating system specifics, etc. (not to mention passwords of course) may in
- fact be used by intruders to gain additional information of a potential
- target.
- Be sure to limit access to application logs if they could hold private or
- security\-related data. Besides the obvious candidates like usernames and
- passwords, things like URLs, cookies or even filenames could also hold
- sensitive data.
- To avoid this problem, you must of course use your common sense. Often, you
- can just edit out the sensitive data or just search/replace your true
- information with faked data.
- .SH setuid applications using libcurl
- libcurl\-using applications that set the \(aqsetuid\(aq bit to run with elevated or
- modified rights also implicitly give that extra power to libcurl and this
- should only be done after careful considerations.
- Giving setuid powers to the application means that libcurl can save files using
- those new rights (if for example the \fISSLKEYLOGFILE\fP environment variable is
- set). Also: if the application wants these powers to read or manage secrets
- that the user is otherwise not able to view (like credentials for a login
- etc), it should be noted that libcurl still might understand proxy environment
- variables that allow the user to redirect libcurl operations to use a proxy
- controlled by the user.
- .SH File descriptors, fork and NTLM
- An application that uses libcurl and invokes \fIfork()\fP gets all file
- descriptors duplicated in the child process, including the ones libcurl
- created.
- libcurl itself uses \fIfork()\fP and \fIexecl()\fP if told to use the
- \fBCURLAUTH_NTLM_WB\fP authentication method which then invokes the helper
- command in a child process with file descriptors duplicated. Make sure that
- only the trusted and reliable helper program is invoked!
- .SH Secrets in memory
- When applications pass usernames, passwords or other sensitive data to
- libcurl to be used for upcoming transfers, those secrets are kept around as\-is
- in memory. In many cases they are stored in the heap for as long as the handle
- itself for which the options are set.
- If an attacker can access the heap, like maybe by reading swap space or via a
- core dump file, such data might be accessible.
- Further, when eventually closing a handle and the secrets are no longer
- needed, libcurl does not explicitly clear memory before freeing it, so
- credentials may be left in freed data.
- .SH Saving files
- libcurl cannot protect against attacks where an attacker has write access to
- the same directory where libcurl is directed to save files.
- .SH Cookies
- If libcurl is built with PSL (\fBPublic Suffix List\fP) support, it detects and
- discards cookies that are specified for such suffix domains that should not be
- allowed to have cookies.
- if libcurl is \fInot\fP built with PSL support, it has no ability to stop super
- cookies.
- .SH Report Security Problems
- Should you detect or just suspect a security problem in libcurl or curl,
- contact the project curl security team immediately. See
- https://curl.se/dev/secprocess.html for details.
- .SH SEE ALSO
- .BR libcurl-thread (3)
|