Package: release.debian.org Severity: normal Tags: trixie X-Debbugs-Cc: curl@packages.debian.org Control: affects -1 + src:curl User: release.debian.org@packages.debian.org Usertags: pu [ Reason ] The curl package version in Debian Trixie suffers from three minor CVEs: [1]: https://security-tracker.debian.org/tracker/CVE-2025-9086 [2]: https://security-tracker.debian.org/tracker/CVE-2025-10148 [3]: https://security-tracker.debian.org/tracker/CVE-2025-11563 The updated package version contains the backported upstream patches to close those vulnerabilities and also two bug fixes for wcurl: a man page fix and a fix to allow overriding the output file name with --curl-options. [ Impact ] If the update is not approved, all curl installations on Debian Trixie machines will remain vulnerable to the exploits: - CVE-2025-9086 allows for an out-of-bound read for cookie path - A fixed mask pattern discovered in CVE-2025-10148 allows a malicious server to induce traffic between the two communicating parties that could be interpreted by an involved proxy (configured or transparent) as genuine, real, HTTP traffic with content and thereby poison its cache. That cached poisoned content could then be served to all users of that proxy. - CVE-2025-11563 is a path traversal vulnerability where users might end up with the downloaded files placed in a folder outside of the current working directory unintentionally. Regarding the additional wcurl fixes: - The manpage fix is for an example invocation where the user wants downloads to be resumed, it's an important use case and was reported by a user. - The fix for overriding the output filename with --curl-options is not that important, given users will use --output directly, but the fix is extremely straightforward. [ Tests ] All upstream tests run successfully. Samuel Henrique <samueloph> has also run the reproducer for CVE-2025-9086 manually and confirmed that the patch fixes the issue. [ Risks ] Errors in backporting the patches which either don't close the vulnerabilities or introduce regressions which are not caught by the upstream tests. The cookie handling patch with the fix for CVE-2025-9086 could be carried over as is from upstream: https://salsa.debian.org/debian/curl/-/commit/700cf2ca7aa6b461c37f28f4f2634850dbf3b971 The websocket patch for CVE-2025-10148 required some backporting to make the expected return types match: https://salsa.debian.org/debian/curl/-/commit/98f245da1dee1f4c549cd3b826a8bcc49cb03d71 The wcurl patches only required minimal backporting changes: https://salsa.debian.org/debian/curl/-/commit/a50e1fa30dd7a58af13d4ce029352520b4e20dd1 https://salsa.debian.org/debian/curl/-/commit/84b76ed84665be069b70b14b0a857a6440708d9b https://salsa.debian.org/debian/curl/-/commit/84e8794b04007dbc07db29ea3b3ab66873339986 [ Checklist ] [x] *all* changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in (old)stable [x] the issue is verified as fixed in unstable [ Changes ] * Backported patch to not drop leading slash in cookie path if that is its only component. * Backported patch which ensures the use of a new, random mask for each outgoing frame on websockets. * Backported wcurl patches for the CVE, manpage fix, and output filename overriding fix. * salsa-ci.yml: Disable arm builds, they are currently broken. [ Other info ] Nothing that I am aware of.
diff -Nru curl-8.14.1/debian/changelog curl-8.14.1/debian/changelog
--- curl-8.14.1/debian/changelog 2025-06-11 19:18:58.000000000 +0100
+++ curl-8.14.1/debian/changelog 2025-10-05 22:03:32.000000000 +0100
@@ -1,3 +1,20 @@
+curl (8.14.1-2+deb13u1) trixie; urgency=medium
+
+ [ Alex ]
+ * Team upload.
+ * d/p/cookie-don-t-treat-the-leading-slash-as-trailing: import upstream
+ patch to fix CVE-2025-9086
+ * d/p/CVE-2025-10148.patch: backport upstream patch for CVE-2025-10148
+
+ [ Samuel Henrique ]
+ * Import wcurl patches.
+ * wcurl-CVE-2025-11563.patch: Fix CVE-2025-11563
+ * wcurl-Fix-example-for-continue-at.patch: Fix example in manpage
+ * wcurl-Set-CURL_OPTIONS-right-before-the-url.patch: Fix to allow
+ --output to be overwritten with --curl-options
+
+ -- Alex <alex@puer-robustus.eu> Sun, 05 Oct 2025 23:03:32 +0200
+
curl (8.14.1-2) unstable; urgency=medium
* gbp pq import/export: Updated hunks offsets
diff -Nru curl-8.14.1/debian/patches/cookie-don-t-treat-the-leading-slash-as-trailing.patch curl-8.14.1/debian/patches/cookie-don-t-treat-the-leading-slash-as-trailing.patch
--- curl-8.14.1/debian/patches/cookie-don-t-treat-the-leading-slash-as-trailing.patch 1970-01-01 01:00:00.000000000 +0100
+++ curl-8.14.1/debian/patches/cookie-don-t-treat-the-leading-slash-as-trailing.patch 2025-10-05 22:03:32.000000000 +0100
@@ -0,0 +1,54 @@
+From c6ae07c6a541e0e96d0040afb62b45dd37711300 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <daniel@haxx.se>
+Date: Mon, 11 Aug 2025 20:23:05 +0200
+Subject: [PATCH] cookie: don't treat the leading slash as trailing
+
+If there is only a leading slash in the path, keep that. Also add an
+assert to make sure the path is never blank.
+
+Reported-by: Google Big Sleep
+Closes #18266
+---
+ lib/cookie.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/lib/cookie.c b/lib/cookie.c
+index 914a4aca1..b72dd99bc 100644
+--- a/lib/cookie.c
++++ b/lib/cookie.c
+@@ -296,9 +296,9 @@ static char *sanitize_cookie_path(const char *cookie_path)
+ /* Let cookie-path be the default-path. */
+ return strdup("/");
+
+- /* remove trailing slash */
++ /* remove trailing slash when path is non-empty */
+ /* convert /hoge/ to /hoge */
+- if(len && cookie_path[len - 1] == '/')
++ if(len > 1 && cookie_path[len - 1] == '/')
+ len--;
+
+ return Curl_memdup0(cookie_path, len);
+@@ -965,7 +965,7 @@ replace_existing(struct Curl_easy *data,
+ clist->spath && co->spath && /* both have paths */
+ clist->secure && !co->secure && !secure) {
+ size_t cllen;
+- const char *sep;
++ const char *sep = NULL;
+
+ /*
+ * A non-secure cookie may not overlay an existing secure cookie.
+@@ -974,8 +974,9 @@ replace_existing(struct Curl_easy *data,
+ * "/loginhelper" is ok.
+ */
+
+- sep = strchr(clist->spath + 1, '/');
+-
++ DEBUGASSERT(clist->spath[0]);
++ if(clist->spath[0])
++ sep = strchr(clist->spath + 1, '/');
+ if(sep)
+ cllen = sep - clist->spath;
+ else
+--
+2.47.3
+
diff -Nru curl-8.14.1/debian/patches/CVE-2025-10148.patch curl-8.14.1/debian/patches/CVE-2025-10148.patch
--- curl-8.14.1/debian/patches/CVE-2025-10148.patch 1970-01-01 01:00:00.000000000 +0100
+++ curl-8.14.1/debian/patches/CVE-2025-10148.patch 2025-10-05 22:03:32.000000000 +0100
@@ -0,0 +1,64 @@
+From 84db7a9eae8468c0445b15aa806fa7fa806fa0f2 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <daniel@haxx.se>
+Date: Mon, 8 Sep 2025 14:14:15 +0200
+Subject: [PATCH] ws: get a new mask for each new outgoing frame
+
+Reported-by: Calvin Ruocco
+Closes #18496
+
+Backported-by: Samuel Henrique <samueloph@debian.org>
+Backported-by: Alex <alex@puer-robustus.eu>
+Changes:
+* Refresh patch context for lib/ws.c
+* Adapt return value to current function return type
+
+---
+ lib/ws.c | 28 +++++++++++++---------------
+ 1 file changed, 13 insertions(+), 15 deletions(-)
+
+diff --git a/lib/ws.c b/lib/ws.c
+index fc02025..7f5af7c 100644
+--- a/lib/ws.c
++++ b/lib/ws.c
+@@ -831,6 +831,18 @@ static ssize_t ws_enc_write_head(struct Curl_easy *data,
+ enc->payload_remain = enc->payload_len = payload_len;
+ ws_enc_info(enc, data, "sending");
+
++ /* 4 bytes random */
++
++ *err = Curl_rand(data, (unsigned char *)&enc->mask, sizeof(enc->mask));
++ if(*err)
++ return -1;
++
++#ifdef DEBUGBUILD
++ if(getenv("CURL_WS_FORCE_ZERO_MASK"))
++ /* force the bit mask to 0x00000000, effectively disabling masking */
++ memset(&enc->mask, 0, sizeof(enc->mask));
++#endif
++
+ /* add 4 bytes mask */
+ memcpy(&head[hlen], &enc->mask, 4);
+ hlen += 4;
+@@ -1025,21 +1037,7 @@ CURLcode Curl_ws_accept(struct Curl_easy *data,
+ subprotocol not requested by the client), the client MUST Fail
+ the WebSocket Connection. */
+
+- /* 4 bytes random */
+-
+- result = Curl_rand(data, (unsigned char *)&ws->enc.mask,
+- sizeof(ws->enc.mask));
+- if(result)
+- return result;
+-
+-#ifdef DEBUGBUILD
+- if(getenv("CURL_WS_FORCE_ZERO_MASK"))
+- /* force the bit mask to 0x00000000, effectively disabling masking */
+- memset(ws->enc.mask, 0, sizeof(ws->enc.mask));
+-#endif
+-
+- infof(data, "[WS] Received 101, switch to WebSocket; mask %02x%02x%02x%02x",
+- ws->enc.mask[0], ws->enc.mask[1], ws->enc.mask[2], ws->enc.mask[3]);
++ infof(data, "[WS] Received 101, switch to WebSocket");
+
+ /* Install our client writer that decodes WS frames payload */
+ result = Curl_cwriter_create(&ws_dec_writer, data, &ws_cw_decode,
diff -Nru curl-8.14.1/debian/patches/series curl-8.14.1/debian/patches/series
--- curl-8.14.1/debian/patches/series 2025-06-11 19:18:58.000000000 +0100
+++ curl-8.14.1/debian/patches/series 2025-10-05 22:03:32.000000000 +0100
@@ -6,3 +6,13 @@
tool_getparam_fix_ftp_pasv.patch
curl_path_make_SFTP_handle_a_path.patch
tool_operate_fix_return_code_when_retry_is_used_but_not_triggered.patch
+
+# CVE-2025-9086
+cookie-don-t-treat-the-leading-slash-as-trailing.patch
+
+CVE-2025-10148.patch
+
+wcurl-Set-CURL_OPTIONS-right-before-the-url.patch
+wcurl-Fix-example-for-continue-at.patch
+# CVE-2025-11563
+wcurl-CVE-2025-11563.patch
diff -Nru curl-8.14.1/debian/patches/wcurl-CVE-2025-11563.patch curl-8.14.1/debian/patches/wcurl-CVE-2025-11563.patch
--- curl-8.14.1/debian/patches/wcurl-CVE-2025-11563.patch 1970-01-01 01:00:00.000000000 +0100
+++ curl-8.14.1/debian/patches/wcurl-CVE-2025-11563.patch 2025-10-05 22:03:32.000000000 +0100
@@ -0,0 +1,71 @@
+From 524f7e733237cd26553dfd76adda521d3150d852 Mon Sep 17 00:00:00 2001
+From: Samuel Henrique <samueloph@debian.org>
+Date: Sun, 12 Oct 2025 14:39:46 +0100
+Subject: [PATCH] Don't percent-decode '/' and '\' in output file name
+
+Co-Authored-by: Sergio Durigan Junior <sergiodj@sergiodj.net>
+
+Backported-by: Samuel Henrique <samueloph@debian.org>
+ * Modify wcurl patch to apply on curl sources by changing the location of the
+ wcurl script from wcurl to scripts/wcurl.
+ * Drop changes to wcurl's tests as they are not in the curl sources.
+ * Swap placement of logical AND (&&) operator in conditions of the if
+ statement to match the new approach; i.e.; they are written in the beginning
+ of the line instead of the end now.
+---
+ scripts/wcurl | 28 +++++++++++++++++++++++++---
+ 1 file changed, 25 insertions(+), 3 deletions(-)
+
+diff --git a/scripts/wcurl b/scripts/wcurl
+index 84b981a..3d768a1 100755
+--- a/scripts/wcurl
++++ b/scripts/wcurl
+@@ -113,6 +113,13 @@ readonly PER_URL_PARAMETERS="\
+ --remote-time \
+ --retry 5 "
+
++# Valid percent-encode codes that are considered unsafe to be decoded.
++# This is a list of space-separated percent-encoded uppercase
++# characters.
++# 2F = /
++# 5C = \
++readonly UNSAFE_PERCENT_ENCODE="2F 5C"
++
+ # Whether to invoke curl or not.
+ DRY_RUN="false"
+
+@@ -137,6 +144,20 @@ is_subset_of()
+ esac
+ }
+
++# Indicate via exit code whether the HTML code given in the first
++# parameter is safe to be decoded.
++is_safe_percent_encode()
++{
++ upper_str=$(printf "%s" "${1}" | tr "[:lower:]" "[:upper:]")
++ for unsafe in ${UNSAFE_PERCENT_ENCODE}; do
++ if [ "${unsafe}" = "${upper_str}" ]; then
++ return 1
++ fi
++ done
++
++ return 0
++}
++
+ # Print the given string percent-decoded.
+ percent_decode()
+ {
+@@ -151,9 +172,10 @@ percent_decode()
+ decode_out="${decode_out}${decode_hex2}"
+ # Skip decoding if this is a control character (00-1F).
+ # Skip decoding if DECODE_FILENAME is not "true".
+- if is_subset_of "${decode_hex1}" "23456789abcdefABCDEF" && \
+- is_subset_of "${decode_hex2}" "0123456789abcdefABCDEF" && \
+- [ "${DECODE_FILENAME}" = "true" ]; then
++ if [ "${DECODE_FILENAME}" = "true" ] \
++ && is_subset_of "${decode_hex1}" "23456789abcdefABCDEF" \
++ && is_subset_of "${decode_hex2}" "0123456789abcdefABCDEF" \
++ && is_safe_percent_encode "${decode_out}"; then
+ # Use printf to decode it into octal and then decode it to the final format.
+ decode_out="$(printf "%b" "\\$(printf %o "0x${decode_hex1}${decode_hex2}")")"
+ fi
diff -Nru curl-8.14.1/debian/patches/wcurl-Fix-example-for-continue-at.patch curl-8.14.1/debian/patches/wcurl-Fix-example-for-continue-at.patch
--- curl-8.14.1/debian/patches/wcurl-Fix-example-for-continue-at.patch 1970-01-01 01:00:00.000000000 +0100
+++ curl-8.14.1/debian/patches/wcurl-Fix-example-for-continue-at.patch 2025-10-05 22:03:32.000000000 +0100
@@ -0,0 +1,40 @@
+From 946caf42d51ada8e11f19f7d06268dfc18a589fe Mon Sep 17 00:00:00 2001
+From: Samuel Henrique <samueloph@debian.org>
+Date: Sun, 21 Sep 2025 18:58:46 +0200
+Subject: [PATCH] Fix example for "continue-at"
+
+ It stopped working after we introduced the "--no-clobber" option, to
+ make the example work again we just need to explicitly override it with
+ "--clobber".
+
+ Thanks to Thomas Braun for reporting it.
+
+ Closes: https://github.com/curl/wcurl/issues/61
+
+Co-authored-by: Sergio Durigan Junior <github@sergiodj.net>
+
+Backported-by: Samuel Henrique <samueloph@debian.org>
+ * Modify wcurl patch to apply on curl sources by changing the location of the
+ wcurl script from wcurl to scripts/wcurl.
+ * Drop changes to wcurl's README file as they are not in the curl sources.
+---
+ docs/wcurl.md | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/docs/wcurl.md b/docs/wcurl.md
+index 4111af5..1864500 100644
+--- a/docs/wcurl.md
++++ b/docs/wcurl.md
+@@ -124,10 +124,9 @@ Download a file passing the **--progress-bar** and **--http2** flags to curl:
+
+ **wcurl --curl-options="--progress-bar --http2" example.com/filename.txt**
+
+-Resume from an interrupted download (if more options are used, this needs to
+-be the last one in the list):
++* Resume from an interrupted download. The options necessary to resume the download (`--clobber --continue-at -`) must be the **last** options specified in `--curl-options`. Note that the only way to resume interrupted downloads is to allow wcurl to overwrite the destination file:
+
+-**wcurl --curl-options="--continue-at -" example.com/filename.txt**
++**wcurl --curl-options="--clobber --continue-at -" example.com/filename.txt**
+
+ # AUTHORS
+
diff -Nru curl-8.14.1/debian/patches/wcurl-Set-CURL_OPTIONS-right-before-the-url.patch curl-8.14.1/debian/patches/wcurl-Set-CURL_OPTIONS-right-before-the-url.patch
--- curl-8.14.1/debian/patches/wcurl-Set-CURL_OPTIONS-right-before-the-url.patch 1970-01-01 01:00:00.000000000 +0100
+++ curl-8.14.1/debian/patches/wcurl-Set-CURL_OPTIONS-right-before-the-url.patch 2025-10-05 22:03:32.000000000 +0100
@@ -0,0 +1,33 @@
+From 57f544e831fcad6eca21760a3233b6b3f7e36fce Mon Sep 17 00:00:00 2001
+From: Samuel Henrique <samueloph@debian.org>
+Date: Sun, 21 Sep 2025 19:32:46 +0200
+Subject: [PATCH] Set CURL_OPTIONS right before the url
+
+ I'm reordering the parameters used in the curl invocation to have
+ "CURL-OPTIONS" be set for last, allowing "--output" to also be
+ overwritten and making the curl invocation more clear, as having
+ "--continue-at -" not right before the URL looks weird.
+
+ As far as my tests went, this has no functionality side effect other
+ than allowing "output" to be set by the user.
+
+Backported-by: Samuel Henrique <samueloph@debian.org>
+ * Modify wcurl patch to apply on curl sources by changing the location of the
+ wcurl script from wcurl to scripts/wcurl.
+---
+ scripts/wcurl | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/scripts/wcurl b/scripts/wcurl
+index af66ae7..84b981a 100755
+--- a/scripts/wcurl
++++ b/scripts/wcurl
+@@ -231,7 +231,7 @@ exec_curl()
+ [ -z "${OUTPUT_PATH}" ] && OUTPUT_PATH=index.html
+ fi
+ # shellcheck disable=SC2086
+- set -- "$@" ${NEXT_PARAMETER} ${PER_URL_PARAMETERS} ${CURL_HAS_NO_CLOBBER} ${CURL_OPTIONS} --output "${OUTPUT_PATH}" "${url}"
++ set -- "$@" ${NEXT_PARAMETER} ${PER_URL_PARAMETERS} ${CURL_HAS_NO_CLOBBER} --output "${OUTPUT_PATH}" ${CURL_OPTIONS} "${url}"
+ NEXT_PARAMETER="--next"
+ done
+
diff -Nru curl-8.14.1/debian/salsa-ci.yml curl-8.14.1/debian/salsa-ci.yml
--- curl-8.14.1/debian/salsa-ci.yml 2025-06-11 19:18:58.000000000 +0100
+++ curl-8.14.1/debian/salsa-ci.yml 2025-10-05 22:03:32.000000000 +0100
@@ -3,7 +3,4 @@
- https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/recipes/debian.yml
variables:
- SALSA_CI_DISABLE_BUILD_PACKAGE_ARM64: 0
- SALSA_CI_DISABLE_BUILD_PACKAGE_ARMEL: 0
- SALSA_CI_DISABLE_BUILD_PACKAGE_ARMHF: 0
SALSA_CI_DPKG_BUILDPACKAGE_ARGS: --build-profiles=nocheck
-- Alex # No gods, no masters. # 47A5 9C45 FA69 E651 25ED 0B98 9891 FC5D 3C3C 4426
Attachment:
signature.asc
Description: PGP signature