CVE-2026-91957
Executive Summary
CVE-2026-91957 is a use-after-free (CWE-416) vulnerability in the FreeRDP smartcard RDPDR device handler, present in versions before 3.31.0. The flaw is triggered when worker thread creation fails after a device has been registered, causing the device pointer to be deallocated while devman retains a dangling reference. Because exploitation requires the attacker to induce a thread-creation failure during channel setup and relies on user interaction to establish an RDP session, the CVSS base score is 3.1 (Low), with primary impact limited to availability and a theoretical path to code execution.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
FreeRDP is an open-source implementation of the Remote Desktop Protocol (RDP), used by both client and server components across Linux, macOS, Windows, and embedded environments. This CVE affects the RDPDR (RDP Device Redirection) smartcard device handler, which is responsible for exposing smartcard devices to the remote session.
The vulnerability class is a use-after-free in the device registration cleanup path. Per the NVD description, when a device is registered with the device manager (devman) but the subsequent worker thread creation fails, the error-handling path deallocates the device structure. However, devman retains a reference (pointer) to that now-freed device. This creates a dangling pointer: any later access to the device via devman dereferences freed memory.
This is a classic lifecycle/ownership bug — the registration and thread-creation steps are not transactionally coupled. The failure of thread creation should either (a) unregister the device from devman before freeing it, or (b) defer freeing until the reference is released. Instead, the cleanup path frees the object while the registry still points to it.
Attack surface: The RDPDR channel and its smartcard sub-protocol. The triggering condition is a resource-exhaustion or environmental failure that causes worker thread creation to fail — for example, thread/process limits, memory pressure, or a race during channel setup. Because this is an internal failure condition rather than a remote controllable primitive in the traditional sense, the attack complexity is rated High (AC:H) in the CVSS vector, and User Interaction is Required (UI:R) since a session must be established.
Note on detail: The NVD description does not name specific functions, structs, or files beyond "smartcard RDPDR device handler", "worker thread", devman, and "device pointer". No public patch diff or PoC was available at time of writing (Patch Confidence 2/4 — claimed in OSV only). Code-level specifics below are therefore limited to what the description supports.
Exploitation Scenarios
Because no public PoC or exploit code exists, the following chain is inferred at the vulnerability-class level, not from a known exploit.
- Reconnaissance / target identification. An attacker identifies a host running a vulnerable FreeRDP build (< 3.31.0) that participates in an RDP session involving smartcard redirection (RDPDR). This is most relevant to FreeRDP-based clients connecting to attacker-influenced or resource-constrained servers, or FreeRDP server components used in thin-client/V DI scenarios.
- Triggering the flaw. During channel setup, the attacker (or an induced condition) causes worker thread creation to fail after the device has already been registered with
devman. This is the precondition for the use-after-free — the device pointer is freed whiledevmanstill references it. - Execution method (class level). Once the dangling reference exists, a subsequent operation that dereferences the freed device via
devmanconstitutes the use-after-free. Because the CVSS vector shows C:N/I:N/A:L, the realistically demonstrable impact is a crash (denial of service); the description notes a possible path to code execution, but this is not demonstrated and would depend on heap layout control (hard with AC:H, UI:R). - Post-exploitation impact. In the DoS case, the session/process terminates. In a hypothetical code-execution outcome, an attacker could gain the privileges of the FreeRDP process — but no public evidence supports weaponization.
Impact Assessment
- Confidentiality: None (C:N). The vector does not assign confidentiality impact.
- Integrity: None (I:N). No integrity impact in the vector.
- Availability: Low (A:L). The primary realistic outcome is a crash/DoS of the affected process or session.
- Scope: Unchanged (S:U). Impact is confined to the vulnerable component.
- Blast radius: Limited to FreeRDP instances using smartcard/RDPDR redirection on versions < 3.31.0. Enterprise exposure is concentrated in VDI, thin-client, and remote-access deployments that rely on FreeRDP for RDP connectivity or device redirection.
- Business impact: Low-to-moderate. Exploitation is difficult (AC:H), requires user interaction, and yields availability impact. Nonetheless, an unexplained FreeRDP crash in a VDI/RDP environment should be investigated, as it may indicate an attempt to trigger this condition.
Detection Guidance
Sigma Rule
title: Potential FreeRDP Smartcard RDPDR Use-After-Free Trigger (CVE-2026-91957)
id: 8f2c1a4e-3b7d-4c9e-9d10-2026freerdp01
status: experimental
description: Detects abnormal FreeRDP process crashes that may be consistent with a use-after-free in the smartcard RDPDR handler when worker thread creation fails.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-91957
author: valtersit.com
date: 2026/01/01
logsource:
product: linux
service: syslog
detection:
selection_proc:
- 'freerdp'
- 'xfreerdp'
- 'wlfreerdp'
selection_crash:
- 'segmentation fault'
- 'double free'
- 'use-after-free'
- 'AddressSanitizer: heap-use-after-free'
selection_thread:
- 'thread creation'
- 'pthread_create'
- 'failed to create'
condition: selection_proc and selection_crash and selection_thread
falsepositives:
- Legitimate FreeRDP crashes from unrelated bugs
- ASan-enabled test builds
level: low
YARA Rule
rule CVE_2026_91957_FreeRDP_RDPDR_UAF
{
meta:
description = "Detects FreeRDP binaries potentially affected by CVE-2026-91957 (smartcard RDPDR use-after-free)"
author = "valtersit.com"
date = "2026-01-01"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-91957"
cve = "CVE-2026-91957"
strings:
$rdpdr = "rdpdr" nocase
$smartcard = "smartcard" nocase
$devman = "devman" nocase
$client = "FreeRDP" nocase
$version = /3\.(2[0-9]|30)\.[0-9]+/ ascii // pre-3.31.0 hint
condition:
uint32(0) == 0x464C457F and // ELF magic
$client and
$rdpdr and
($smartcard or $devman) and
$version
}
Suricata IDS Rule
alert tcp any any -> any 3389 (msg:"Potential FreeRDP RDPDR smartcard channel abuse (CVE-2026-91957)"; flow:established,to_server; content:"|03 00|"; content:"rdpdr"; nocase; content:"smartcard"; nocase; threshold: type limit, track by_src, count 1, seconds 60; reference:cve,2026-91957; classtype:attempted-dos; sid:202691957; rev:1;)
Elastic Detection
process where event.type in ("start", "end") and
process.name in ("freerdp", "xfreerdp", "wlfreerdp") and
process.exit_code != 0
Splunk SPL Query
index=main (process_name="freerdp" OR process_name="xfreerdp" OR process_name="wlfreerdp")
("segmentation fault" OR "use-after-free" OR "double free" OR "pthread_create" OR "thread creation failed")
| stats count min(_time) as first_seen max(_time) as last_seen by host, process_name, message
| where count > 0
| eval severity="low"
| table first_seen, last_seen, host, process_name, message, severity
Wazuh OSSEC Rule
<group name="freerdp,cve-2026-91957,">
<rule id="202691" level="5">
<decoded_as>syslog</decoded_as>
<match>freerdp|xfreerdp|wlfreerdp</match>
<match>segmentation fault|use-after-free|double free</match>
<description>CVE-2026-91957: FreeRDP smartcard RDPDR use-after-free crash detected</description>
<mitre>
<id>T1203</id>
</mitre>
</rule>
</group>
Mitigation & Patch Guidance
Patch Confidence: 2/4 — CLAIMED. A fix is asserted in OSV for FreeRDP 3.31.0, but this has not been independently confirmed via vendor advisory or commit diff.
- Immediate mitigations
- Disable smartcard / RDPDR device redirection in FreeRDP configs where not required (reduces the attack surface entirely).
- Constrain thread availability to reduce the chance of induced thread-creation failure; monitor for thread exhaustion.
- Restrict who can initiate RDP sessions and limit exposure of RDP endpoints to trusted networks only.
- Patch / upgrade steps
- Upgrade FreeRDP to 3.31.0 or later once the release is verified in your dependency chain.
- Confirm the fix in the upstream repository changelog/commit before relying on the OSV claim alone (single-source).
- Rebuild any embedded/thin-client images that vendor FreeRDP.
- Long-term hardening
- Track FreeRDP advisories via the project's security policy (security@freerdp.com).
- Adopt memory-safety tooling (ASan/valgrind) in CI to catch lifecycle/UAF regressions.
- Apply least privilege to RDP client/server processes and segment RDP traffic.
References
- NVD — https://nvd.nist.gov/vuln/detail/CVE-2026-91957
- OSV — https://osv.dev/vulnerability/CVE-2026-91957 (claimed patch source, unconfirmed)
- FreeRDP Project — https://www.freerdp.com/
- FreeRDP Security Policy — https://github.com/FreeRDP/FreeRDP/security
- MITRE CWE-416 (Use After Free) — https://cwe.mitre.org/data/definitions/416.html
Exploitation in the wild: None observed. CISA KEV: NO. No public PoC, Nuclei template, or exploit code available. No threat-actor campaign attributed at time of writing.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.