Per MQTT 3.1.1 sections 3.13.1 and 3.14.1, PINGRESP and DISCONNECT fixed
headers must have remaining_length set to zero. The previous code
dispatched to mqtt->nextstate based on the queued state alone without
validating remaining_length for these no-payload packet types, allowing
a malicious broker to send a PINGRESP with non-zero remaining_length
whose trailing bytes would be interpreted as the payload of whatever
message type was queued (CONNACK, SUBACK, etc.).
The exploitation path turned out to be narrow — curl sends data to the
server the user chose to talk to — but the spec violation and the
resulting protocol-state error are real. Reject the malformed packets
with CURLE_WEIRD_SERVER_REPLY before state dispatch.
Reported-by: Raymond Steen <raymond@vortiqxconsilium.com>
Found by VORTIQ-X VXF Framework
Bug: https://hackerone.com/reports/3702718
Signed-off-by: Raymond Steen <raymond@vortiqxconsilium.com>
Closes#21465
Fix to create the top directory `foo` when specified as
`X:foo\bar\filename`, on Windows and MS-DOS. Add test to verify.
Caught by Codex Security
Follow-up to 787ee935ac#16566Closes#21449
When a user supplies an IP address to use for the HAPROXY protocol,
the IP version reported must be deduced from the address and has
no relation to the IP version used for the upstream connection.
Add test3220 to verify.
Fixes#21340
Reported-by: Fiona Klute
Closes#21341
To make it scoped for the single request appropriately.
Reported-by: Muhamad Arga Reksapati
Verify with libtest 2504: a custom Host *disabled* on reused handle
Closes#21312
This should return a SSL_CTX pointer but it was accidentally broken.
Verify with test 1587
Follow-up to 2db8ae480f
Spotted by Codex Security
Closes#21290
... unless it is a POST and the user explicitly asked to keep doing
POST.
Add test1983/1984: verify --follow with 303 and PUT + custom GET
Fixes#20715
Reported-by: Dan Arnfield
Closes#21280
via env `CURL_TEST_SSH_KEYALGO`, `rsa` (default), `ecdsa`, `ed25519`.
To ease debugging and testing and to make these code paths more
universal.
Closes#21223
Now the logic for handling name duplicates and picking the longest
expiry and strictest subdomain is the same for the callback as for when
reading from file.
Also strip trailing dots from the hostname added by the callback.
A minor side-effect is that the hostname provided by the callback can
now enable subdomains by starting the name with a dot, but we discourage
using such hostnames in documentation.
Amended test 1915 to verify.
Closes#21201
Up from 1K.
Reduces the risk that someone could flush the list by tricking a user to
do many transfers to new hostnames.
Document the limit.
Follow-up to 03a792b186Closes#21200
Avoid never-ending growth.
When adding more entries, it now deletes the first entry in the list,
which is the oldest added entry still held in memory. I decided to avoid
a Least Recently Used concept as I suspect with a list with this many
entries most entries have not been used, and we don't save the timestamp
of recent use anyway.
The net effect might (no matter what) be that the removed entry might
feel a bit "random" in the eyes of the user.
Verify with test 1674
Ref #21183Closes#21190
Avoid never-ending growth.
When adding more entries, it now deletes the first entry in the list,
which is the oldest added entry still held in memory. I decided to avoid
a Least Recently Used concept as I suspect with a list with this many
entries most entries have not been used, and we don't save the timestamp
of recent use anyway.
The net effect might (no matter what) be that the removed entry might
feel a bit "random" in the eyes of the user.
Verify with test 1669.
Reported-by: Geeknik Labs
Fixes#21183Closes#21189
A previous refactor changed the TAB check so that the octet could be
accepted in the 'path', which would cause an invalid line in the saved
cookie file so not possible to read the cookie back. Not terrible
because the path cannot contain a raw tab anyway so it would never match
anyway.
Add test 1685 to verify
Reported-by: Izan on hackerone
Closes#21185
If there is no trailing file name for -O or --remote-name-all, continue
searching until there is no more to search. A URL ending with multiple
slashes would previously make it do wrong.
Add test 1639 and 1644 to verify.
Follow-up to e26eefd9ce
Reported-by: James Fuller
Closes#21165
New connection filter `cf-dns` that manages DNS queries. If hands
out addresses and HTTPS-RR records to anyone interested. Used by
HTTPS and IP happy eyeballing.
Information may become available *before* the libcurl "dns entry"
is complete, e.g. all queries have been answered. The cf-ip-happy
filter uses this information to start connection attempts as soon
as the first address is available.
The multi MSTATE_RESOLVING was removed. A new connection always
goes to MSTATE_CONNECTING. The connectdata bit `dns_resolved`
indicates when DNS information is complete. This is used for
error reporting and starting the progress meter.
Removed dns entries `data->state.dns[i]`, as the `cf-dns` filter
now keeps the reference now.
Many minor tweaks for making this work and pass address information
around safely.
Closes#21027
Add test1715 to check proper handling of chunked transfer
encoding in CONNECT responses. Change proxy error code from
56 (RECV_ERROR) for everything to 7 (COULDNT_CONNECT) when
the server response could be read successfully, but establishing
the connection is not possible (http status code wrong).
Adapt several test expectations from 56 to 7.
Closes#21084
Use a thread queue and pool for asnyc threaded DNS resolves.
Add pytest test_21_* for verification.
Add `CURLMOPT_RESOLVE_THREADS_MAX` to allow applications to
resize the thread pool used.
Add `CURLMOPT_QUICK_EXIT` to allow applications to skip thread
joins when cleaning up a multi handle. Multi handles in
`curl_easy_perform()` inherit this from `CURLOPT_QUICK_EXIT`.
Add several debug environment variables for testing.
Closes#20936
Add test case 1673 to do repeated upload failures and verify there is no
leak. This proved a previous leak and now it verifies the fix.
Reported-by: James Fuller
Closes#21062
... and apply the CURLOPT_MAXFILESIZE limit (if set) on that as well.
This effectively protects the user against "zip bombs".
Test case 1618 verifies using a 14 byte brotli payload that otherwise
explodes to 102400 zero bytes.
Closes#20787
When skipping macdef lines inside netrc files, ignore it completely and
do not tokenize or bail out on bad quotes.
Verify in test 1672
Follow-up to 3b43a05e00
Spotted by Codex Security
Closes#21049
- librtmp has no test cases, makes no proper releases and has not had a
single commit within the last year
- librtmp parses the URL itself and requires non-compliant URLs for this
- we have no RTMP tests
- RTMP was used by 2.2% of curl users (self-identified in the 2025
survey)
Closes#20673
Replace the `volatile int dirty` with a reference counter
protected by a mutex when available.
Solve the problem of when to call application's lock function
by adding a volatile flag that indicates a share has been added
to easy handles in its lifetime. That flag ever goes from
FALSE to TRUE, so volatile might work (in the absence of a mutex).
(The problem is that the lock/unlock functions need 2-3
`curl_share_setopt()` invocations to become usable and there
is no way of telling if the third will ever happen. Calling
the lock function before the 3rd setopt may crash the
application.)
When removing a share from an easy handle (or replacing it with
another share), detach the easy connection on a share with a
connection pool.
When cleaning up a share, allow this even if it is still used in
easy handles. It will be destroyed when the reference count
drops to 0.
Closes#20870
A previous refactor made the parser more lenient and this takes it back
to making sure only ascii digits are accepted.
Added test 1684 to verify
Follow-up to 304b5183fd
Pointed out by Codex Security
Closes#21041