☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]
Freerdp logo [ WEBSITE ] [ VENDOR STATS ]
CVSS: 6.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H 🐛 CWE-476
👁️
Common Weakness Enumeration - Identifies the specific category of software weakness or flaw.

CVE-2026-91954

CVE-2026-91954 Null Pointer Dereference in FreeRDP
📅 PUBLISHED: 2026-09-15 00:00 UTC 🔄 UPDATED: 2026-10-09 10:28 UTC
[ OFFICIAL PATCH DEPLOYED ↓ ] FIX: LIKELY — 2 distinct-origin sources confirm fix
[ DEFENSE PATCH ↓ ]
💣 PoC: Public
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 0.38%
👁️
0.38% probability
9.5× above the median CVE
Tier: ELEVATED
30-day exploitation window · FIRST.org · updated daily
🥷 MITRE: T1190
👁️
MITRE ATT&CK Tactic - Describes the strategy hackers use to execute this attack.
Country: Global License: Open Source
Affected: Freerdp — upgrade to patched release
CVSS VECTOR BREAKDOWN 6.5
AV: N Attack Vector Network
AC: L Attack Complexity Low
PR: N Privileges Required None
UI: R User Interaction Required
S: U Scope Unchanged
C: N Confidentiality None
I: N Integrity None
A: H Availability High
6.5
THREAT LEVEL
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2026-91954 is a null pointer dereference (CWE-476) in the FreeRDP client's gdi_surface_bits function, triggered when processing a crafted RDP Surface Bits command that declares the NSCodec codec ID. A malicious or compromised RDP server can crash any connecting FreeRDP client — including when NSCodec support is disabled — resulting in a client-side denial of service. The vulnerability carries a CVSS v3.1 base score of 6.5 and affects FreeRDP versions prior to 3.31.0.

⚡ AUTOMATE YOUR CVE INTELLIGENCE

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.

›Patch confidence — UNVERIFIED to CONFIRMED, cross-referenced NVD + RHSA + Debian
›Exploit & PoC — poc_status, poc_url, has_exploit. Not in NVD.
›Shodan dorks — ready-made queries to find exposed vulnerable systems
›Detection rules — YARA · Wazuh · Elastic (all plans) · Sigma (Pro)
›pending_fields — know exactly which of 7 fields NVD hasn't processed yet
›Free backfill — data incomplete when you paid? Re-check within 30 days = 0 credits
PAYG €0.08/lookup Standard €19/mo (was €29) · 5k credits Pro €65/mo (was €99) · 20k credits FOUNDING PRICE · LOCKED FOR LIFE · ENDS 31 DEC 2026
[ FROM €19/MO ]
Free sandbox key available
No signup required

Technical Analysis

FreeRDP is an open-source implementation of the Remote Desktop Protocol (RDP), used by client applications on Linux, macOS, and Windows, as well as in embedded and server-side tooling. The vulnerability resides in the GDI subsystem's handling of Surface Bits commands — an RDP update type used to transmit raw bitmap data to the client's graphics pipeline.

According to the NVD description, the null pointer dereference occurs in the function gdi_surface_bits when the incoming Surface Bits command specifies the NSCodec codec ID. NSCodec is a Microsoft RemoteFX-era codec used for efficient bitmap compression. The critical detail is that the crash occurs even when the codec is disabled on the client — meaning the vulnerable code path does not validate codec availability before dereferencing a codec-context structure that has not been initialized.

The vulnerability class is a classic uninitialized/missing-context dereference: a codec dispatch path assumes a decoder context (or function table) exists for the declared codec ID, but because NSCodec was administratively disabled, that context is NULL. The subsequent dereference crashes the process. Because the trigger is a server-supplied command in the RDP data stream, the attack is network-borne and requires only that a victim client connect to a hostile or man-in-the-middle-controlled RDP endpoint.

Attack surface: The RDP client's inbound graphics update parser. Any deployment where FreeRDP initiates outbound RDP connections to endpoints the user does not fully control (public jump hosts, BYOD remoting, automation that connects to third-party hosts).

Root cause characteristics (per CWE-476): missing NULL check on the codec context prior to use; codec enablement state not consulted during the dispatch decision for Surface Bits payloads.

No further code-level structure (struct names, parameter names, allocation routines) is disclosed in the NVD description; those details should not be assumed.


Impact Assessment

CVSS v3.1: 6.5 (Medium)

Subscore Value Interpretation
Attack Vector (AV:N) Network Triggered over the RDP connection
Attack Complexity (AC:L) Low No race, no special conditions
Privileges Required (PR:N) None Requires no authentication to the client
User Interaction (UI:R) Required Victim must connect to the malicious server
Scope (S:U) Unchanged Impact confined to the client process
Confidentiality (C:N) None No data disclosure
Integrity (I:N) None No data modification
Availability (A:H) High Full process crash / client termination

Business impact: Availability-only. A successful exploit terminates the FreeRDP client session, dropping the user's remote desktop and any unsaved work in the client context. In automated/headless deployments (kiosks, thin clients, CI runners, monitoring gateways that bridge to RDP hosts), a malicious server can repeatedly kill client processes, causing persistent service disruption.

Blast radius: Bounded to individual client processes. No persistence, no code execution, no lateral movement is implied by the CVSS vector or vulnerability class. The scope is Unchanged — the crash does not escape the client trust boundary. Impact scales with the number of FreeRDP clients that connect to attacker-influenced RDP endpoints.

EPSS: 0.00346 (~28th percentile) — low probability of exploitation in the wild, consistent with the absence of public PoC and the availability-only, client-crash nature of the bug. CISA KEV: No. Not currently associated with known adversary campaigns.


Exploitation Scenarios

No public PoC is available. The following chain is inferred strictly from the vulnerability class (null pointer dereference in a codec dispatch path) and the specific trigger described in the NVD entry (crafted Surface Bits command with NSCodec codec ID).

1. Reconnaissance / Target Identification An adversary operates or compromises an RDP server that FreeRDP clients connect to. Targets are identified by observing FreeRDP client connections — either via a server they control (e.g., a public jump host, phishing-delivered .rdp connection, or a malicious VDI entry) or by positioning on the network path (MITM) to inject into an existing connection. No client authentication is needed by the attacker; only the client's willingness to connect (UI:R).

2. Triggering the Flaw Once the FreeRDP client connects, the malicious server sends a Surface Bits command whose payload declares the NSCodec codec ID. Because the vulnerable code in gdi_surface_bits fails to validate that a valid codec context exists before dereferencing it, the command drives the client into a NULL dereference — irrespective of whether NSCodec was administratively disabled.

3. Payload / Execution Method The "payload" is simply a malformed/unsupported-codec Surface Bits command embedded in the normal RDP graphics update stream. No additional exploit primitive is required — the crash is immediate on parse. This is a pure availability attack at the protocol-message level.

4. Post-Exploitation Impact The FreeRDP client process crashes (availability loss). No code execution, no credential theft, no lateral movement is implied. Repeat delivery yields a persistent denial of service against clients forced to reconnect to the hostile endpoint.


Detection Guidance

Detection must focus on the server-to-client direction of the RDP stream — an unusual inversion from typical RDP detections, which monitor inbound connections to exposed RDP servers. Because the connection is outbound from the FreeRDP client and the trigger is a protocol-level graphics command, detection is best approached through endpoint telemetry (process crashes), memory-corruption signatures, and — where deep packet inspection of RDP is available — anomalous Surface Bits/NSCodec traffic.

Sigma Rule

title: FreeRDP Client Crash - Surface Bits NSCodec Null Pointer Dereference (CVE-2026-91954)
id: 8a3f1c2e-5b4d-4e7a-9c1b-2d6f0a9e4b71
status: experimental
description: Detects FreeRDP client process crashes consistent with CVE-2026-91954,
  a null pointer dereference in gdi_surface_bits triggered by a crafted Surface Bits
  command declaring the NSCodec codec ID from a malicious RDP server.
references:
  - https://nvd.nist.gov/vuln/detail/CVE-2026-91954
author: valtersit.com Threat Intelligence
date: 2026/01/01
logsource:
  category: process_creation
  product: windows
detection:
  selection_img:
    Image|endswith:
      - '\wfreerdp.exe'
      - '\xfreerdp.exe'
  selection_crash:
    CommandLine|contains:
      - 'freerdp'
  selection_event:
    EventID:
      - 1000   # Application Error
      - 1001   # Windows Error Reporting
  condition: selection_img and selection_event
falsepositives:
  - Legitimate FreeRDP client crashes unrelated to NSCodec
  - Debugging sessions
level: medium
tags:
  - attack.t1190
  - cve.2026.91954

YARA Rule

rule CVE_2026_91954_FreeRDP_NSCodec_NullDeref
{
    meta:
        author = "valtersit.com Threat Intelligence"
        description = "Detects FreeRDP binaries referencing the gdi_surface_bits code path and NSCodec strings associated with CVE-2026-91954"
        reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-91954"
        cve = "CVE-2026-91954"
        date = "2026-01-01"

    strings:
        $freerdp = "FreeRDP" ascii wide nocase
        $func    = "gdi_surface_bits" ascii wide
        $nscodec = "NSCodec" ascii wide nocase
        $surface = "Surface Bits" ascii wide nocase

    condition:
        uint16(0) == 0x5A4D and
        filesize < 50MB and
        $freerdp and
        (
            ($func and $nscodec) or
            ($surface and $nscodec)
        )
}

Suricata IDS Rule

alert tcp any 3389 -> any any (msg:"CVE-2026-91954 FreeRDP Surface Bits NSCodec Null Pointer Dereference Attempt"; flow:from_server,established; content:"|00 00 00 00|"; content:"NSCodec"; nocase; within:100; content:"Surface"; nocase; within:200; classtype:attempted-dos; reference:cve,2026-91954; reference:url,nvd.nist.gov/vuln/detail/CVE-2026-91954; sid:202691954; rev:1;)

Note: The exact RDP wire encoding of Surface Bits/NSCodec is not disclosed in the CVE data; the rule above matches the observable string artifacts and should be refined against a packet capture of the actual trigger in a lab before production deployment.

Elastic Detection

process where process.name in ("wfreerdp.exe", "xfreerdp.exe") and
event.action == "process-exited" and
event.outcome == "crash"

EQL variant for Windows event telemetry:

sequence by host.name
  [process where process.name : "wfreerdp.exe" or process.name : "xfreerdp.exe"]
  [any where event.category == "process" and event.type == "stop" and process.exit_code != 0]

Splunk SPL Query

index=windows (sourcetype=WinEventLog:Application OR sourcetype=WinEventLog:Security)
(
  EventCode=1000 OR EventCode=1001
)
(Message="freerdp*" OR Message="*gdi_surface_bits*" OR Message="*NSCodec*")
| stats count min(_time) as first_seen max(_time) as last_seen
        by host, Message
| convert ctime(first_seen) ctime(last_seen)
| sort - count

Wazuh OSSEC Rule

<group name="freerdp,cve_2026_91954,">
  <rule id="100954" level="10">
    <decoded_as>json</decoded_as>
    <field name="process.name">wfreerdp.exe|xfreerdp.exe</field>
    <field name="event.outcome">crash</field>
    <description>CVE-2026-91954: FreeRDP client crash (possible Surface Bits/NSCodec null pointer dereference)</description>
    <mitre>
      <id>T1190</id>
    </mitre>
    <group>availability</group>
  </rule>

  <rule id="100955" level="12">
    <if_sid>100954</if_sid>
    <field name="event.reason">access violation|segmentation fault|SIGSEGV|null pointer</field>
    <description>CVE-2026-91954: FreeRDP client crash with memory fault signature (high confidence exploitation)</description>
    <mitre>
      <id>T1190</id>
    </mitre>
  </rule>
</group>

Mitigation & Patch Guidance

Patch confidence: 2/4 (CLAIMED) — A single source (OSV) indicates the issue is resolved in FreeRDP 3.31.0. This fix has not been independently confirmed against the upstream commit or vendor advisory. Treat as provisional and verify before relying on it operationally.

1. Immediate mitigations

  • Where possible, disable NSCodec on the FreeRDP client — although note the CVE explicitly states the crash occurs even when the codec is disabled, so this is not a reliable workaround; it reduces attack surface but does not eliminate the flaw.
  • Restrict FreeRDP clients to connecting only to trusted, administratively controlled RDP endpoints; avoid connecting to public/untrusted RDP hosts.
  • Deploy network segmentation to prevent MITM injection into RDP sessions.
  • Where MTI protection exists, enforce TLS/tunneled RDP to prevent transcript tampering.

2. Patch / upgrade steps

  • Upgrade FreeRDP to 3.31.0 or later. Verify the fix against the upstream repository changelog and the OSV advisory before considering the issue closed.
  • For package-managed installs (Debian/Ubuntu/RHEL/Homebrew), track the distribution's backport advisory.
  • Validate the fixed build by testing a FreeRDP client against a lab RDP server that emits a Surface Bits command declaring NSCodec with the codec disabled.

3. Long-term hardening

  • Adopt a client allowlist policy for outbound RDP destinations.
  • Monitor client crash telemetry centrally (as shown in the detection rules) to identify attack attempts.
  • Maintain a rapid patch cadence for RDP client binaries, given their exposure in the inbound graphics-parsing path.
  • Contribute a regression test upstream so that the Surface Bits/NSCodec dispatch path is covered against future regressions.

References

Exploit-in-the-wild evidence: None. CISA KEV: No. No public PoC, no Nuclei template, no exploit code available. EPSS 0.00346 (28th percentile) — low exploitation likelihood. No known threat actor campaigns are associated with this CVE at the time of writing.

👁️ SHODAN DORKS (THREAT HUNTING)

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.

product:

💣 PoC CODE AVAILABLE

Exploit code for this CVE is tracked in our database. Access poc_code via API Pro.

[ API_PRO ] →
◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2026-91954/ · CVE data: NVD/MITRE (public domain) · © 2026 ValtersIT Hub
>_ SYSTEM_CORE: INTEL_ACTIVE
90% TEAM-CURATED // 10% AUTOMATED INGESTION.
ALL PATCH REFERENCES AND VERSION DATA SOURCED FROM NVD + OSV OFFICIAL REGISTRIES.