ANT-2026-D5W3VWPN · freerdp/freerdp
heap-buffer-overflow high
CVE-2026-68579 GHSA-m37j-jcr2-8gcc
Severity Claude high · Security research firm high · Maintainer -
Discovered by Claude Mythos Preview
Anthropic's analysis, sealed at approval. Disclosure to the maintainer was performed by Ada Logics.
ANT-2026-D5W3VWPN: Windows clipboard stream read ignores caller buffer size
The Windows FreeRDP client's IStream::Read implementation for remote clipboard files (CliprdrStream_Read, wf_cliprdr.c:249) calls CopyMemory(pv, clipboard->req_fdata, clipboard->req_fsize) where req_fsize is taken directly from the server's CLIPRDR_FILE_CONTENTS_RESPONSE (wf_cliprdr.c:2449, cliprdr_common.c:377) and never compared to the caller's buffer size cb before the copy. The resulting IStream is handed to arbitrary paste consumers (e.g., explorer.exe) via OleSetClipboard and IDataObject::GetData. A malicious RDP server can answer a small FILECONTENTS_RANGE read with an arbitrarily large payload, and the client memcpy()s the entire attacker-controlled payload into the consumer's fixed-size buffer. This yields a scope-changing heap overflow with attacker-controlled content in a process outside the RDP client, enabling code execution.
Target
Project: freerdp/freerdp
Location: client/Windows/wf_cliprdr.c:249
Discovery: static analysis — not yet dynamically reproduced
Technical Details
req_fsize is assigned directly from fileContentsResponse->cbRequested, which is derived from the server-sent PDU dataLen (response->cbRequested = response->common.dataLen - 4) with no validation or correlation to the original requested size. The only size comparison (req_fsize < cb at wf_cliprdr.c:256) runs after the CopyMemory and only handles short reads, so an oversized server response is copied in full before any check occurs.
Reproduction
- Attacker's RDP server advertises CFSTR_FILEDESCRIPTORW / CFSTR_FILECONTENTS on the shared clipboard
- Victim presses Ctrl+V in Explorer; Explorer obtains the IStream from FreeRDP's IDataObject and calls IStream::Read(pv, 0x1000, &read)
- FreeRDP sends a FILECONTENTS_RANGE request for 0x1000 bytes
- Server replies with a CB_FILECONTENTS_RESPONSE carrying ~0x100000 bytes of attacker data
- wf_cliprdr_server_file_contents_response() sets req_fsize=0x100000; CliprdrStream_Read() CopyMemory()s 1 MiB into Explorer's 4 KiB buffer
[No reproducer or sanitizer output attached — request from security-cvd@anthropic.com if needed.]
Suggested Fix
Clamp the bytes copied and reported in CliprdrStream_Read to min(cb, server-returned size), and treat server responses larger than the requested range as a protocol error; retain the requested size from cliprdr_send_request_filecontents() so it can be validated against the response.
Acknowledgement
This vulnerability was discovered by Claude, Anthropic's AI assistant, and triaged by the Anthropic security team in collaboration with Anthropic Research. Please direct questions to security-cvd@anthropic.com and reference ANT-2026-D5W3VWPN.
Reference: ANT-2026-D5W3VWPN
Anthropic CVD Policy: https://www.anthropic.com/coordinated-vulnerability-disclosure
Triage and disclosure were performed by Ada Logics. The writeup below is the document the firm sent to the maintainer.
- Verdict
- true positive
- Severity
- high
This issue was found using AI and agents, and has been reviewed manually.
This is a Windows-only issues, but I don't have access to a Window machine so did not create an end-to-end windows reproducer. I left out a harness-based Linux reproducer to as I think auditing the code should be sufficient to identify the vulnerability. Let me know if you need more information from me and I will see if I can extract it.
Summary
FreeRDP's Windows client exposes clipboard file contents to OLE paste consumers
(e.g. explorer.exe) through a COM IStream. When the consumer calls
IStream::Read(pv, cb, …) — pv is its own fixed-size buffer of cb bytes —
CliprdrStream_Read() asks the RDP server for the data via a
CB_FILECONTENTS_RANGE request, then copies the server's response into pv using
the server-supplied length (req_fsize), not cb:
CopyMemory(pv, clipboard->req_fdata, clipboard->req_fsize); // length is server-controlled
A malicious or compromised RDP server answers the bounded request with an
arbitrarily large CB_FILECONTENTS_RESPONSE; req_fsize becomes the attacker's
chosen size and the copy overflows the consumer's buffer with attacker-controlled
content.
Affected versions
- FreeRDP
master— HEAD5e8e987b469b60a3bafadf8f5afc40f91c09f458,client/Windows/wf_cliprdr.c:249(CliprdrStream_Read): the copy still usesclipboard->req_fsizewith no clamp tocb. Unpatched. - FreeRDP 3.x — present in the released Windows client.
- Appears novel — no GHSA/CVE found for
CliprdrStream_Readcopying a server-controlled length.
Details
All line numbers at master HEAD 5e8e987b, client/Windows/wf_cliprdr.c.
// CliprdrStream_Read() :225
static HRESULT STDMETHODCALLTYPE CliprdrStream_Read(IStream* This, void* pv, ULONG cb,
ULONG* pcbRead)
{
...
/* Ask the server for the file contents (bounded request of cb bytes). */
ret = cliprdr_send_request_filecontents(clipboard, (void*)This, instance->m_lIndex,
FILECONTENTS_RANGE, instance->m_lOffset.QuadPart, cb);
if (ret < 0)
return E_FAIL;
if (clipboard->req_fdata)
{
CopyMemory(pv, clipboard->req_fdata, clipboard->req_fsize); // :249 cb is IGNORED
free(clipboard->req_fdata);
}
...
}
req_fsize / req_fdata are set by the channel callback
wf_cliprdr_server_file_contents_response() directly from the server's
CB_FILECONTENTS_RESPONSE PDU (the CopyMemory of the server payload is around
:2455). Nothing constrains req_fsize to the cb the consumer passed, so the
copy at :249 writes req_fsize bytes into a cb-byte buffer. cb is the size
the paste consumer requested (commonly a small, fixed value); req_fsize is
whatever the server put in the response.
Reach: OLE paste consumer → IStream::Read → CliprdrStream_Read →
cliprdr_send_request_filecontents (server round-trip) → CopyMemory overflow.
Impact
A malicious/compromised RDP server overflows a fixed-size heap buffer in the OLE
paste consumer (e.g. explorer.exe) with attacker-controlled bytes when a user
pastes server-offered clipboard file contents — a classic attacker-content heap
overflow, in a process outside the RDP client.
Suggested fix
Clamp the copy to the caller's buffer size, and report only what fits:
if (clipboard->req_fdata)
{
- CopyMemory(pv, clipboard->req_fdata, clipboard->req_fsize);
+ ULONG n = (clipboard->req_fsize < cb) ? clipboard->req_fsize : cb;
+ CopyMemory(pv, clipboard->req_fdata, n);
free(clipboard->req_fdata);
}
- *pcbRead = clipboard->req_fsize;
- instance->m_lOffset.QuadPart += clipboard->req_fsize;
+ *pcbRead = n;
+ instance->m_lOffset.QuadPart += n;
(An IStream::Read must never write more than cb bytes into pv; a server
returning more than requested should be treated as a short read or an error.)
References
client/Windows/wf_cliprdr.c(master5e8e987b) —CliprdrStream_Read(:225, overflowingCopyMemoryat:249), server file-contents response handler (CopyMemoryof the server payload near:2455).- CWE-787 (Out-of-bounds Write), CWE-120, CWE-130.
Attribution
This issue was found using AI and agents, and has been reviewed manually. Please credit Claude and Ada Logics — found by Anthropic using agents to study the security of open-source projects, with Ada Logics validating and reporting. Let us know if you need any more information.
Disclosure
We follow coordinated disclosure policy here: https://www.anthropic.com/coordinated-vulnerability-disclosure (90 day deadline).
The change that resolved this finding.
diff --git a/client/Windows/wf_cliprdr.c b/client/Windows/wf_cliprdr.c
index 70895ba3999c..c0a6feea6f3d 100644
--- a/client/Windows/wf_cliprdr.c
+++ b/client/Windows/wf_cliprdr.c
@@ -225,25 +225,27 @@ static ULONG STDMETHODCALLTYPE CliprdrStream_Release(IStream* This)
static HRESULT STDMETHODCALLTYPE CliprdrStream_Read(IStream* This, void* pv, ULONG cb,
ULONG* pcbRead)
{
- int ret;
CliprdrStream* instance = (CliprdrStream*)This;
- wfClipboard* clipboard;
if (!pv || !pcbRead || !instance)
return E_INVALIDARG;
- clipboard = (wfClipboard*)instance->m_pData;
+ wfClipboard* clipboard = (wfClipboard*)instance->m_pData;
*pcbRead = 0;
if (instance->m_lOffset.QuadPart >= instance->m_lSize.QuadPart)
return S_FALSE;
- ret = cliprdr_send_request_filecontents(clipboard, (void*)This, instance->m_lIndex,
- FILECONTENTS_RANGE, instance->m_lOffset.QuadPart, cb);
+ const int ret =
+ cliprdr_send_request_filecontents(clipboard, (void*)This, instance->m_lIndex,
+ FILECONTENTS_RANGE, instance->m_lOffset.QuadPart, cb);
if (ret < 0)
return E_FAIL;
+ if (clipboard->req_fsize > cb)
+ return E_FAIL;
+
if (clipboard->req_fdata)
{
CopyMemory(pv, clipboard->req_fdata, clipboard->req_fsize);https://github.com/FreeRDP/FreeRDP/commit/680426e58a986b6fd0f1c352624f813708fc3432
Recorded dates, in order.
- 2026-04-02 Discovered or logged
- 2026-07-16 Patch released
- 2026-07-22 Sent to maintainer
- 2026-07-22 Maintainer acknowledged
- 2026-09-28 Publicly revealed
SHA-3-512 hash:
94f4c703ec61699c8fd0ad4be74e234d085309ee2bb5837ca53b81cda8e86e1c3929d5ff789e4decaa75dca0af0433f6ba2a82a3f0d4299ddb8fd529d6f8a703
Committed 2026-07-22 07:29 UTC
Revealed 2026-09-28 21:38 UTC
Verify (download preimage.json)
Show preimage JSON
{
"ant_id": "ANT-2026-D5W3VWPN",
"bug_class": "Heap Buffer Overflow",
"claude_severity": "high",
"commit_sha": null,
"created_at": "2026-04-16T01:52:39+00:00",
"description": "The Windows FreeRDP client's IStream::Read implementation for remote clipboard files (CliprdrStream_Read, wf_cliprdr.c:249) calls CopyMemory(pv, clipboard->req_fdata, clipboard->req_fsize) where req_fsize is taken directly from the server's CLIPRDR_FILE_CONTENTS_RESPONSE (wf_cliprdr.c:2449, cliprdr_common.c:377) and never compared to the caller's buffer size cb before the copy. The resulting IStream is handed to arbitrary paste consumers (e.g., explorer.exe) via OleSetClipboard and IDataObject::GetData. A malicious RDP server can answer a small FILECONTENTS_RANGE read with an arbitrarily large payload, and the client memcpy()s the entire attacker-controlled payload into the consumer's fixed-size buffer. This yields a scope-changing heap overflow with attacker-controlled content in a process outside the RDP client, enabling code execution.",
"discovered_at": "2026-04-02T00:00:00+00:00",
"location": "client/Windows/wf_cliprdr.c:249",
"poc_sha256": null,
"preimage_version": 1,
"project": "freerdp/freerdp",
"reproduction": [
"1. Attacker's RDP server advertises CFSTR_FILEDESCRIPTORW / CFSTR_FILECONTENTS on the shared clipboard",
"2. Victim presses Ctrl+V in Explorer; Explorer obtains the IStream from FreeRDP's IDataObject and calls IStream::Read(pv, 0x1000, &read)",
"3. FreeRDP sends a FILECONTENTS_RANGE request for 0x1000 bytes",
"4. Server replies with a CB_FILECONTENTS_RESPONSE carrying ~0x100000 bytes of attacker data",
"5. wf_cliprdr_server_file_contents_response() sets req_fsize=0x100000; CliprdrStream_Read() CopyMemory()s 1 MiB into Explorer's 4 KiB buffer"
],
"technical_details": "req_fsize is assigned directly from fileContentsResponse->cbRequested, which is derived from the server-sent PDU dataLen (response->cbRequested = response->common.dataLen - 4) with no validation or correlation to the original requested size. The only size comparison (req_fsize < cb at wf_cliprdr.c:256) runs after the CopyMemory and only handles short reads, so an oversized server response is copied in full before any check occurs.",
"title": "Windows clipboard stream read ignores caller buffer size",
"vendor_severity": "high"
}