FlawOpen

flawopen.com/Incidents/citrix-bleed-session-token-leak-october-2023

● Citrix · CVE-2023-4966 · October 2023 · CVSS 9.4 · Critical
FlawOpen Security Research

Citrix Bleed: session-token leak and MFA bypass

CVE-2023-4966 exposed NetScaler memory, including session tokens, enabling session hijacking that bypassed MFA. Exploitation began in late Aug. 2023.[1], [2]

💡 Plain English Explainer (ELI5)

You ask an assistant to copy a message onto a small card and tell you how long it is. The card only fits 50 characters, so they write 50 — but when you ask how long the message was, they honestly answer "800 characters", because that is how long the original was. You then hand someone the card and tell them to read 800 characters from it. They read your 50, then keep going into whatever was printed on the rest of the sheet.[2]

Core Concepts & Subsystem Terms

snprintf
A C function that formats text into a fixed-size buffer. When the text does not fit it truncates, but it returns the length the full text would have had.[3]
NetScaler ADC / Gateway
Citrix appliances that provide remote access and load balancing at the network edge. Only those configured as a Gateway or AAA virtual server were affected.[1]
Buffer over-read (CWE-125)
Reading past the end of a buffer. Nothing is overwritten, but whatever happens to sit in the adjacent memory is disclosed. This describes the specific out-of-bounds-read mechanism (CWE-125); Citrix classifies CVE-2023-4966 broadly as CWE-119.[1], [3]
Session token
The value that proves a user already logged in. Whoever presents it is treated as that user, without a password or MFA prompt.[2]

Framework mappings

Incident Timeline

2023-08

Exploitation of the flaw as a zero-day begins, according to later incident-response reporting.[2]

2023-10-10

Citrix publishes bulletin CTX579459 with fixed builds 14.1-8.50, 13.1-49.15 and 13.0-92.19.[1]

2023-10-18

CISA adds CVE-2023-4966 to its Known Exploited Vulnerabilities catalog.[4]

Step-by-Step Attack Flow

Step 1

An oversized header

An unauthenticated request with a very long Host header reaches code that builds an OpenID Connect discovery response on the appliance.[2], [3]

Step 2

The length is misread

snprintf truncates the text to fit the buffer, but returns the full would-be length, and the code treats that as the number of bytes written.[3], [2]

Step 3

Memory past the buffer is sent

The response is sent using that larger length, so the appliance returns adjacent memory along with the truncated JSON.[2]

Step 4

Sessions are taken over

The leaked memory can include valid session tokens. Replaying one gives the attacker the user's logged-in session without a password or MFA.[2], [1]

Source Code: Flaw vs. Secure Implementation

Illustrative C, not NetScaler source. The fix checks snprintf's return value, which is the length the complete output would have had. If it is negative or at least the buffer size, formatting failed or was truncated, so the function sends nothing. The length passed to send_response is therefore used only when the complete response fits in buf.[3], [2]

UNPATCHED FLAW
#include <stdio.h>

int send_response(const char *data, int len);

int send_oidc_config(const char *host)
{
    char buf[256];
    /* n is what WOULD have been written, which may exceed sizeof(buf) */
    int n = snprintf(buf, sizeof(buf), "{\"issuer\":\"https://%s\"}", host);
    return send_response(buf, n);   /* sends n bytes, reading past buf */
}
HARDENED SECURE PATCH
#include <stdio.h>

int send_response(const char *data, int len);

int send_oidc_config(const char *host)
{
    char buf[256];
    int n = snprintf(buf, sizeof(buf), "{\"issuer\":\"https://%s\"}", host);
    if (n < 0 || (size_t)n >= sizeof(buf))
        return -1;                  /* reject truncated output; never send beyond the buffer */
    return send_response(buf, n);
}

Engineering & System Hardening Checklist

Sources