diff --git a/pkgs/tools/networking/curl/CVE-2022-32221.patch b/pkgs/tools/networking/curl/CVE-2022-32221.patch
new file mode 100644
index 000000000000..cefa68e19763
--- /dev/null
+++ b/pkgs/tools/networking/curl/CVE-2022-32221.patch
@@ -0,0 +1,216 @@
+combination of upstream a64e3e59938abd7d667e4470a18072a24d7e9de9 (fix)
+and 1edb15925e350be3b891f8a8de86600b22c0bb20 (test)
+
+diff --git a/lib/setopt.c b/lib/setopt.c
+index 03c4efdbf1e58..7289a4e78bdd0 100644
+--- a/lib/setopt.c
++++ b/lib/setopt.c
+@@ -700,6 +700,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
+ }
+ else
+ data->set.method = HTTPREQ_GET;
++ data->set.upload = FALSE;
+ break;
+
+ case CURLOPT_HTTPPOST:
+diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
+index 20a37fd51..21bf7fcd6 100644
+--- a/tests/data/Makefile.inc
++++ b/tests/data/Makefile.inc
+@@ -223,7 +223,7 @@ test1908 test1909 test1910 test1911 test1912 test1913 test1914 test1915 \
+ test1916 test1917 test1918 \
+ \
+ test1933 test1934 test1935 test1936 test1937 test1938 test1939 test1940 \
+-test1941 test1942 test1943 test1944 test1945 test1946 \
++test1941 test1942 test1943 test1944 test1945 test1946 test1948 \
+ \
+ test2000 test2001 test2002 test2003 test2004 \
+ \
+diff --git a/tests/data/test1948 b/tests/data/test1948
+new file mode 100644
+index 000000000..639523d99
+--- /dev/null
++++ b/tests/data/test1948
+@@ -0,0 +1,73 @@
++
++
++
++HTTP
++HTTP POST
++HTTP PUT
++
++
++
++# Server-side
++
++
++HTTP/1.1 200 OK
++Date: Thu, 01 Nov 2001 14:49:00 GMT
++Content-Type: text/html
++Content-Length: 6
++
++hello
++
++
++HTTP/1.1 200 OK
++Date: Thu, 01 Nov 2001 14:49:00 GMT
++Content-Type: text/html
++Content-Length: 6
++
++hello
++HTTP/1.1 200 OK
++Date: Thu, 01 Nov 2001 14:49:00 GMT
++Content-Type: text/html
++Content-Length: 6
++
++hello
++
++
++
++# Client-side
++
++
++http
++
++
++
++CURLOPT_POST after CURLOPT_UPLOAD reusing handle
++
++
++lib%TESTNUMBER
++
++
++
++http://%HOSTIP:%HTTPPORT/%TESTNUMBER
++
++
++
++# Verify data after the test has been "shot"
++
++
++PUT /%TESTNUMBER HTTP/1.1
++Host: %HOSTIP:%HTTPPORT
++Accept: */*
++Content-Length: 22
++Expect: 100-continue
++
++This is test PUT data
++POST /1948 HTTP/1.1
++Host: %HOSTIP:%HTTPPORT
++Accept: */*
++Content-Length: 22
++Content-Type: application/x-www-form-urlencoded
++
++This is test PUT data
++
++
++
+diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc
+index c12f9689b..01b0d8486 100644
+--- a/tests/libtest/Makefile.inc
++++ b/tests/libtest/Makefile.inc
+@@ -61,7 +61,7 @@ noinst_PROGRAMS = chkhostname libauthretry libntlmconnect \
+ lib1591 lib1592 lib1593 lib1594 lib1596 \
+ lib1905 lib1906 lib1907 lib1908 lib1910 lib1911 lib1912 lib1913 \
+ lib1915 lib1916 lib1917 lib1918 lib1933 lib1934 lib1935 lib1936 \
+- lib1937 lib1938 lib1939 lib1940 lib1945 lib1946 \
++ lib1937 lib1938 lib1939 lib1940 lib1945 lib1946 lib1948 \
+ lib3010 lib3025
+
+ chkdecimalpoint_SOURCES = chkdecimalpoint.c ../../lib/mprintf.c \
+@@ -736,6 +736,10 @@ lib1946_SOURCES = lib1940.c $(SUPPORTFILES)
+ lib1946_LDADD = $(TESTUTIL_LIBS)
+ lib1946_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1946
+
++lib1948_SOURCES = lib1948.c $(SUPPORTFILES)
++lib1948_LDADD = $(TESTUTIL_LIBS)
++lib1948_CPPFLAGS = $(AM_CPPFLAGS)
++
+ lib3010_SOURCES = lib3010.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+ lib3010_LDADD = $(TESTUTIL_LIBS)
+ lib3010_CPPFLAGS = $(AM_CPPFLAGS)
+diff --git a/tests/libtest/lib1948.c b/tests/libtest/lib1948.c
+new file mode 100644
+index 000000000..7c891a2ca
+--- /dev/null
++++ b/tests/libtest/lib1948.c
+@@ -0,0 +1,79 @@
++/***************************************************************************
++ * _ _ ____ _
++ * Project ___| | | | _ \| |
++ * / __| | | | |_) | |
++ * | (__| |_| | _ <| |___
++ * \___|\___/|_| \_\_____|
++ *
++ * Copyright (C) 1998 - 2022, Daniel Stenberg, , et al.
++ *
++ * This software is licensed as described in the file COPYING, which
++ * you should have received as part of this distribution. The terms
++ * are also available at https://curl.haxx.se/docs/copyright.html.
++ *
++ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
++ * copies of the Software, and permit persons to whom the Software is
++ * furnished to do so, under the terms of the COPYING file.
++ *
++ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
++ * KIND, either express or implied.
++ *
++ * SPDX-License-Identifier: curl
++ *
++ ***************************************************************************/
++
++#include "test.h"
++
++typedef struct
++{
++ char *buf;
++ size_t len;
++} put_buffer;
++
++static size_t put_callback(char *ptr, size_t size, size_t nmemb, void *stream)
++{
++ put_buffer *putdata = (put_buffer *)stream;
++ size_t totalsize = size * nmemb;
++ size_t tocopy = (putdata->len < totalsize) ? putdata->len : totalsize;
++ memcpy(ptr, putdata->buf, tocopy);
++ putdata->len -= tocopy;
++ putdata->buf += tocopy;
++ return tocopy;
++}
++
++int test(char *URL)
++{
++ CURL *curl;
++ CURLcode res = CURLE_OUT_OF_MEMORY;
++
++ curl_global_init(CURL_GLOBAL_DEFAULT);
++
++ curl = curl_easy_init();
++ if(curl) {
++ const char *testput = "This is test PUT data\n";
++ put_buffer pbuf;
++
++ /* PUT */
++ curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
++ curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
++ curl_easy_setopt(curl, CURLOPT_READFUNCTION, put_callback);
++ pbuf.buf = (char *)testput;
++ pbuf.len = strlen(testput);
++ curl_easy_setopt(curl, CURLOPT_READDATA, &pbuf);
++ curl_easy_setopt(curl, CURLOPT_INFILESIZE, (long)strlen(testput));
++ res = curl_easy_setopt(curl, CURLOPT_URL, URL);
++ if(!res)
++ res = curl_easy_perform(curl);
++ if(!res) {
++ /* POST */
++ curl_easy_setopt(curl, CURLOPT_POST, 1L);
++ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, testput);
++ curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)strlen(testput));
++ res = curl_easy_perform(curl);
++ }
++ curl_easy_cleanup(curl);
++ }
++
++ curl_global_cleanup();
++ return (int)res;
++}
diff --git a/pkgs/tools/networking/curl/CVE-2022-35252.patch.bin b/pkgs/tools/networking/curl/CVE-2022-35252.patch.bin
new file mode 100644
index 000000000000..909f03575565
--- /dev/null
+++ b/pkgs/tools/networking/curl/CVE-2022-35252.patch.bin
@@ -0,0 +1,103 @@
+combination of upstream 8dfc93e573ca740544a2d79ebb0ed786592c65c3 (fix)
+and 2fc031d834d488854ffc58bf7dbcef7fa7c1fc28 (test)
+
+the final hunk specifically contains dos-style line-endings, so this
+file *must* be treated by git as a binary, hence the extension
+
+diff --git a/lib/cookie.c b/lib/cookie.c
+index 5a4d9e9725f62..ab790a1cdb0ce 100644
+--- a/lib/cookie.c
++++ b/lib/cookie.c
+@@ -441,6 +441,30 @@ static bool bad_domain(const char *domain)
+ return TRUE;
+ }
+
++/*
++ RFC 6265 section 4.1.1 says a server should accept this range:
++
++ cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
++
++ But Firefox and Chrome as of June 2022 accept space, comma and double-quotes
++ fine. The prime reason for filtering out control bytes is that some HTTP
++ servers return 400 for requests that contain such.
++*/
++static int invalid_octets(const char *p)
++{
++ /* Reject all bytes \x01 - \x1f (*except* \x09, TAB) + \x7f */
++ static const char badoctets[] = {
++ "\x01\x02\x03\x04\x05\x06\x07\x08\x0a"
++ "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
++ "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x7f"
++ };
++ size_t vlen, len;
++ /* scan for all the octets that are *not* in cookie-octet */
++ len = strcspn(p, badoctets);
++ vlen = strlen(p);
++ return (len != vlen);
++}
++
+ /*
+ * Curl_cookie_add
+ *
+@@ -595,6 +619,11 @@ Curl_cookie_add(struct Curl_easy *data,
+ badcookie = TRUE;
+ break;
+ }
++ if(invalid_octets(whatptr) || invalid_octets(name)) {
++ infof(data, "invalid octets in name/value, cookie dropped");
++ badcookie = TRUE;
++ break;
++ }
+ }
+ else if(!len) {
+ /*
+diff --git a/tests/data/test8 b/tests/data/test8
+index a8548e6c2ea5a..858761159aa0d 100644
+--- a/tests/data/test8
++++ b/tests/data/test8
+@@ -46,6 +46,36 @@ Set-Cookie: trailingspace = removed; path=/we/want;
+ Set-Cookie: nocookie=yes; path=/WE;
+ Set-Cookie: blexp=yesyes; domain=%HOSTIP; domain=%HOSTIP; expiry=totally bad;
+ Set-Cookie: partialip=nono; domain=.0.0.1;
++Set-Cookie: cookie1=%hex[%01-junk]hex%
++Set-Cookie: cookie2=%hex[%02-junk]hex%
++Set-Cookie: cookie3=%hex[%03-junk]hex%
++Set-Cookie: cookie4=%hex[%04-junk]hex%
++Set-Cookie: cookie5=%hex[%05-junk]hex%
++Set-Cookie: cookie6=%hex[%06-junk]hex%
++Set-Cookie: cookie7=%hex[%07-junk]hex%
++Set-Cookie: cookie8=%hex[%08-junk]hex%
++Set-Cookie: cookie9=%hex[junk-%09-]hex%
++Set-Cookie: cookie11=%hex[%0b-junk]hex%
++Set-Cookie: cookie12=%hex[%0c-junk]hex%
++Set-Cookie: cookie14=%hex[%0e-junk]hex%
++Set-Cookie: cookie15=%hex[%0f-junk]hex%
++Set-Cookie: cookie16=%hex[%10-junk]hex%
++Set-Cookie: cookie17=%hex[%11-junk]hex%
++Set-Cookie: cookie18=%hex[%12-junk]hex%
++Set-Cookie: cookie19=%hex[%13-junk]hex%
++Set-Cookie: cookie20=%hex[%14-junk]hex%
++Set-Cookie: cookie21=%hex[%15-junk]hex%
++Set-Cookie: cookie22=%hex[%16-junk]hex%
++Set-Cookie: cookie23=%hex[%17-junk]hex%
++Set-Cookie: cookie24=%hex[%18-junk]hex%
++Set-Cookie: cookie25=%hex[%19-junk]hex%
++Set-Cookie: cookie26=%hex[%1a-junk]hex%
++Set-Cookie: cookie27=%hex[%1b-junk]hex%
++Set-Cookie: cookie28=%hex[%1c-junk]hex%
++Set-Cookie: cookie29=%hex[%1d-junk]hex%
++Set-Cookie: cookie30=%hex[%1e-junk]hex%
++Set-Cookie: cookie31=%hex[%1f-junk]hex%
++Set-Cookie: cookie31=%hex[%7f-junk]hex%
+
+
+
+@@ -60,7 +90,7 @@ GET /we/want/%TESTNUMBER HTTP/1.1
+ Host: %HOSTIP:%HTTPPORT
+ User-Agent: curl/%VERSION
+ Accept: */*
+-Cookie: name with space=is weird but; trailingspace=removed; cookie=perhaps; cookie=yes; foobar=name; blexp=yesyes
++Cookie: name with space=is weird but; trailingspace=removed; cookie=perhaps; cookie=yes; foobar=name; blexp=yesyes; cookie9=junk- -
+
+
+
diff --git a/pkgs/tools/networking/curl/CVE-2022-42915.patch b/pkgs/tools/networking/curl/CVE-2022-42915.patch
new file mode 100644
index 000000000000..55d46c30d59c
--- /dev/null
+++ b/pkgs/tools/networking/curl/CVE-2022-42915.patch
@@ -0,0 +1,126 @@
+combination of upstream 55e1875729f9d9fc7315cec611bffbd2c817ad89 (fix)
+and 038bfb8522a93328b7e65bd2b6b8387c974b9ac8 (test)
+
+diff --git a/lib/http_proxy.c b/lib/http_proxy.c
+index 1f87f6c62aa40..cc20b3a801941 100644
+--- a/lib/http_proxy.c
++++ b/lib/http_proxy.c
+@@ -212,10 +212,8 @@ void Curl_connect_done(struct Curl_easy *data)
+ Curl_dyn_free(&s->rcvbuf);
+ Curl_dyn_free(&s->req);
+
+- /* restore the protocol pointer, if not already done */
+- if(s->prot_save)
+- data->req.p.http = s->prot_save;
+- s->prot_save = NULL;
++ /* restore the protocol pointer */
++ data->req.p.http = s->prot_save;
+ data->info.httpcode = 0; /* clear it as it might've been used for the
+ proxy */
+ data->req.ignorebody = FALSE;
+diff --git a/lib/url.c b/lib/url.c
+index 690c53c81a3c1..be5ffca2d8b20 100644
+--- a/lib/url.c
++++ b/lib/url.c
+@@ -751,15 +751,6 @@ static void conn_shutdown(struct Curl_easy *data, struct connectdata *conn)
+ DEBUGASSERT(data);
+ infof(data, "Closing connection %ld", conn->connection_id);
+
+-#ifndef USE_HYPER
+- if(conn->connect_state && conn->connect_state->prot_save) {
+- /* If this was closed with a CONNECT in progress, cleanup this temporary
+- struct arrangement */
+- data->req.p.http = NULL;
+- Curl_safefree(conn->connect_state->prot_save);
+- }
+-#endif
+-
+ /* possible left-overs from the async name resolvers */
+ Curl_resolver_cancel(data);
+
+commit 53bd03ce1cf5dd49a8c5ac4dc52bf9e20f438e2f
+Author: Daniel Stenberg
+Date: Thu Oct 6 14:14:25 2022 +0200
+
+ test445: verifies the protocols-over-http-proxy flaw and fix
+
+diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
+index 20a37fd51..8fba66c20 100644
+--- a/tests/data/Makefile.inc
++++ b/tests/data/Makefile.inc
+@@ -71,7 +71,7 @@ test409 test410 test411 test412 test413 \
+ \
+ test430 test431 test432 test433 test434 test435 test436 \
+ \
+-test440 test441 \
++test440 test441 test445 \
+ \
+ test490 test491 test492 test493 test494 \
+ \
+diff --git a/tests/data/test445 b/tests/data/test445
+new file mode 100644
+index 000000000..0406c0f9a
+--- /dev/null
++++ b/tests/data/test445
+@@ -0,0 +1,61 @@
++
++
++
++HTTP
++HTTP proxy
++
++
++
++#
++# Server-side
++
++
++HTTP/1.1 503 no just no
++Date: Tue, 09 Nov 2010 14:49:00 GMT
++Server: test-server/fake
++Accept-Ranges: bytes
++Content-Length: 6
++Connection: close
++
++-foo-
++
++
++
++#
++# Client-side
++
++
++gopher
++dict
++http
++ftp
++imap
++ldap
++mqtt
++pop3
++rtsp
++scp
++sftp
++smb
++smtp
++
++
++http-proxy
++
++
++Refuse tunneling protocols through HTTP proxy
++
++
++-x http://%HOSTIP:%PROXYPORT/%TESTNUMBER -p gopher://127.0.0.1 dict://127.0.0.1 http://moo https://example telnet://another ftp://yes ftps://again imap://more ldap://perhaps mqtt://yes pop3://mail rtsp://harder scp://copy sftp://files smb://wird smtp://send
++
++
++
++#
++# Verify data after the test has been "shot"
++
++# refused in the CONNECT
++
++56
++
++
++
diff --git a/pkgs/tools/networking/curl/CVE-2022-42916.patch b/pkgs/tools/networking/curl/CVE-2022-42916.patch
new file mode 100644
index 000000000000..ab63c6966f6f
--- /dev/null
+++ b/pkgs/tools/networking/curl/CVE-2022-42916.patch
@@ -0,0 +1,131 @@
+From 53bcf55b4538067e6dc36242168866becb987bb7 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg
+Date: Wed, 12 Oct 2022 10:47:59 +0200
+Subject: [PATCH] url: use IDN decoded names for HSTS checks
+
+Reported-by: Hiroki Kurosawa
+
+Closes #9791
+---
+ lib/url.c | 91 ++++++++++++++++++++++++++++---------------------------
+ 1 file changed, 47 insertions(+), 44 deletions(-)
+
+diff --git a/lib/url.c b/lib/url.c
+index a3be56bced9de..690c53c81a3c1 100644
+--- a/lib/url.c
++++ b/lib/url.c
+@@ -2036,10 +2036,56 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
+ failf(data, "Too long host name (maximum is %d)", MAX_URL_LEN);
+ return CURLE_URL_MALFORMAT;
+ }
++ hostname = data->state.up.hostname;
++
++ if(hostname && hostname[0] == '[') {
++ /* This looks like an IPv6 address literal. See if there is an address
++ scope. */
++ size_t hlen;
++ conn->bits.ipv6_ip = TRUE;
++ /* cut off the brackets! */
++ hostname++;
++ hlen = strlen(hostname);
++ hostname[hlen - 1] = 0;
++
++ zonefrom_url(uh, data, conn);
++ }
++
++ /* make sure the connect struct gets its own copy of the host name */
++ conn->host.rawalloc = strdup(hostname ? hostname : "");
++ if(!conn->host.rawalloc)
++ return CURLE_OUT_OF_MEMORY;
++ conn->host.name = conn->host.rawalloc;
++
++ /*************************************************************
++ * IDN-convert the hostnames
++ *************************************************************/
++ result = Curl_idnconvert_hostname(data, &conn->host);
++ if(result)
++ return result;
++ if(conn->bits.conn_to_host) {
++ result = Curl_idnconvert_hostname(data, &conn->conn_to_host);
++ if(result)
++ return result;
++ }
++#ifndef CURL_DISABLE_PROXY
++ if(conn->bits.httpproxy) {
++ result = Curl_idnconvert_hostname(data, &conn->http_proxy.host);
++ if(result)
++ return result;
++ }
++ if(conn->bits.socksproxy) {
++ result = Curl_idnconvert_hostname(data, &conn->socks_proxy.host);
++ if(result)
++ return result;
++ }
++#endif
+
+ #ifndef CURL_DISABLE_HSTS
++ /* HSTS upgrade */
+ if(data->hsts && strcasecompare("http", data->state.up.scheme)) {
+- if(Curl_hsts(data->hsts, data->state.up.hostname, TRUE)) {
++ /* This MUST use the IDN decoded name */
++ if(Curl_hsts(data->hsts, conn->host.name, TRUE)) {
+ char *url;
+ Curl_safefree(data->state.up.scheme);
+ uc = curl_url_set(uh, CURLUPART_SCHEME, "https", 0);
+@@ -2145,26 +2191,6 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
+
+ (void)curl_url_get(uh, CURLUPART_QUERY, &data->state.up.query, 0);
+
+- hostname = data->state.up.hostname;
+- if(hostname && hostname[0] == '[') {
+- /* This looks like an IPv6 address literal. See if there is an address
+- scope. */
+- size_t hlen;
+- conn->bits.ipv6_ip = TRUE;
+- /* cut off the brackets! */
+- hostname++;
+- hlen = strlen(hostname);
+- hostname[hlen - 1] = 0;
+-
+- zonefrom_url(uh, data, conn);
+- }
+-
+- /* make sure the connect struct gets its own copy of the host name */
+- conn->host.rawalloc = strdup(hostname ? hostname : "");
+- if(!conn->host.rawalloc)
+- return CURLE_OUT_OF_MEMORY;
+- conn->host.name = conn->host.rawalloc;
+-
+ #ifdef ENABLE_IPV6
+ if(data->set.scope_id)
+ /* Override any scope that was set above. */
+@@ -3713,29 +3739,6 @@ static CURLcode create_conn(struct Curl_easy *data,
+ if(result)
+ goto out;
+
+- /*************************************************************
+- * IDN-convert the hostnames
+- *************************************************************/
+- result = Curl_idnconvert_hostname(data, &conn->host);
+- if(result)
+- goto out;
+- if(conn->bits.conn_to_host) {
+- result = Curl_idnconvert_hostname(data, &conn->conn_to_host);
+- if(result)
+- goto out;
+- }
+-#ifndef CURL_DISABLE_PROXY
+- if(conn->bits.httpproxy) {
+- result = Curl_idnconvert_hostname(data, &conn->http_proxy.host);
+- if(result)
+- goto out;
+- }
+- if(conn->bits.socksproxy) {
+- result = Curl_idnconvert_hostname(data, &conn->socks_proxy.host);
+- if(result)
+- goto out;
+- }
+-#endif
+
+ /*************************************************************
+ * Check whether the host and the "connect to host" are equal.
diff --git a/pkgs/tools/networking/curl/default.nix b/pkgs/tools/networking/curl/default.nix
index 248a3719021c..d95d8069fbbd 100644
--- a/pkgs/tools/networking/curl/default.nix
+++ b/pkgs/tools/networking/curl/default.nix
@@ -82,8 +82,15 @@ stdenv.mkDerivation rec {
./CVE-2022-32206.patch
./CVE-2022-32207.patch
./CVE-2022-32208.patch
+ ./CVE-2022-35252.patch.bin
+ # CVE-2022-35260 not applicable to 7.83.1
+ ./CVE-2022-32221.patch
+ ./CVE-2022-42915.patch
+ ./CVE-2022-42916.patch
] ++ lib.optional patchNetrcRegression ./netrc-regression.patch;
+ patchFlags = [ "-p1" "--binary" ];
+
outputs = [ "bin" "dev" "out" "man" "devdoc" ];
separateDebugInfo = stdenv.isLinux;