← Back to Attack Research

NetScaler session mixup: the CitrixBleed sibling your probe misses

CitrixBleed taught the world to read NetScaler memory. CVE-2026-4368 is the quieter sibling: a race-condition session mixup on the edge appliance that hands one user another user's authenticated session. A probe that checks a banner or fires a single request never sees it. Here is the decision tree from an unauthenticated request to an internal pivot.

An attacker fires two unauthenticated requests at your NetScaler Gateway a few milliseconds apart, in a tight loop, while a legitimate employee is logging in. One of those requests comes back carrying the employee's authenticated session context: their cookie, their internal reach, their MFA already satisfied. The attacker never read a byte of appliance memory. They never sent a malformed packet. They sent two valid requests and won a race. This is CVE-2026-4368, the race-condition session mixup in NetScaler ADC/Gateway. It is the quiet sibling of CitrixBleed, it does not show up on a banner probe, and a scanner that fires one request at a time will tell you the appliance is clean. Here is the decision tree a real operator walks, and how to actually test for it.

Citrix NetScaler ADC and Gateway appliances sit at the worst possible place to have a session bug: the remote-access and identity boundary. They terminate VPN and ICA-proxy sessions, front AAA virtual servers, act as SAML identity providers, and publish internal applications to the internet. A flaw that lets an attacker obtain someone else's authenticated session on that appliance is not a session bug on a web app. It is a key to the building, with the MFA lock already opened. The 2023 CitrixBleed event (CVE-2023-4966) proved exactly how much damage that buys: Mandiant documented session takeovers that bypassed both password and MFA checks, and CISA tied LockBit 3.0 affiliate ransomware activity to its exploitation.

CVE-2026-4368 reaches the same destination, another user's live session, by a different and quieter road. CitrixBleed was a memory overread: send a crafted request, read session material out of the appliance's memory. The session mixup is a race condition: concurrent requests on a vulnerable build cause the appliance to cross authenticated session context between users. Same prize. Different mechanism. And, critically, a completely different test. This piece walks the operator decision tree from an unauthenticated request to an internal pivot, explains why single-request probes miss it, and gives defenders a test and a fix that actually close it. Verifiable security.

The attack pattern in one paragraph

On an affected NetScaler ADC/Gateway build configured as a Gateway or AAA virtual server, concurrent request handling can cause a session mixup: under the right timing, the appliance associates one connection's response with another connection's authenticated session state. The attacker does not need credentials and does not need to read memory; they need concurrency and timing. By issuing requests in tight, overlapping bursts, using the same single-packet and high-concurrency technique that makes any race condition exploitable, while legitimate users are authenticating, the attacker increases the probability that one of their unauthenticated requests is handed a victim's authenticated session context. The vendor advisory (CTX696300) classifies it as a user-session-mixup issue affecting Gateway/AAA, scored CVSS 7.7, and the appliance has been under in-the-wild attack pressure across the broader 2026 NetScaler advisory cluster. Because the bug is a race, it is non-deterministic: a single probe usually returns a clean, ordinary response. The bug only reveals itself when you generate concurrency and look for the cross-user leak across many attempts.

That non-determinism is the entire reason it slips past commodity tooling. A vulnerability scanner that fires one request, reads one response, and grades it has no way to observe a timing-dependent cross-user leak. It sees a 200, a login page, a normal cookie. It moves on. The appliance is reported clean. The race is still there.

Why this still ships, and why probes miss it

Three structural reasons this class keeps reaching production on identity-boundary appliances, and keeps evading the scans that are supposed to catch it.

  1. Concurrency bugs do not show up in single-request testing. The entire commodity-scanner model is request→response→grade. A race condition has no signature in a single response; it exists only in the relationship between overlapping requests. Tooling that cannot issue tightly-synchronized concurrent requests, and cannot correlate a response to the wrong user's session, is structurally blind to it. The bug is invisible by construction to the way most scanning works.
  2. Banner and version probes are misleading on NetScaler specifically. A common shortcut is to fingerprint the appliance by a header and infer the CVE from a version string. On NetScaler this fails twice over. First, the Via: NS-CACHE-9.3 integrated-cache header is a caching-component signal, not a firmware version. Current 14.1 documentation still shows that exact string in cache examples, so it proves nothing about patch level. Second, CVE-2026-4368's exposure is gated on a specific build (per advisory, build 14.1-66.54) and on the appliance being configured as Gateway or AAA. You cannot read either condition off a banner. Version-string scanning produces false comfort and false alarms in equal measure.
  3. The fix needs more than a patch on the primary node. Like the rest of the CitrixBleed family, remediating a session-integrity issue means not only upgrading every node (primary, HA pair, cluster, DR, SDX-hosted VPX) but also terminating active and persistent sessions after the upgrade. An organization that patches the primary and declares victory leaves live, already-mixed sessions in flight and unpatched failover nodes on the path. Partial remediation reads as "patched" on a version check and remains exploitable in practice.

The attacker decision tree

ATTACKER DECISION TREE Unauth request → Victim's session → Internal pivot NetScaler session mixup (CVE-2026-4368) ┌──────────────────────────────────────────────┐ │ 1. Identify a NetScaler Gateway / AAA edge │ │ - login portal, ICA proxy, AAA vserver │ │ - NS cookies / page family (NOT a banner │ │ version — that proves nothing) │ └────────────────┬─────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────┐ │ 2. Confirm the role gate, not the version │ │ - is it Gateway / AAA (vs LB-only)? │ │ - is the auth/login surface reachable? │ └────────────────┬─────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────┐ │ 3. Generate concurrency, not a single request │ │ - overlapping request bursts (single-packet │ │ / high-concurrency timing) │ │ - aim at the window where REAL users auth │ └────────────────┬─────────────────────────────┘ │ did a response carry a session │ context that is NOT mine? ┌───────┴────────┐ NO │ │ YES ▼ ▼ ┌──────────────┐ ┌──────────────────────────────┐ │ retry across │ │ 4. Capture the mixed-in session│ │ more attempts│ │ - victim cookie / NSC_AAAC │ │ + busier │ │ - already MFA-satisfied │ │ time windows │ └───────────────┬──────────────┘ └──────────────┘ │ ▼ ┌──────────────────────────────────────┐ │ 5. Replay as the victim │ │ - authenticated portal as them │ │ - their entitlements, their apps │ └───────────────┬───────────────────────┘ │ ▼ ┌──────────────────────────────────────┐ │ 6. Pivot to internal estate │ │ - published apps / VDI / ICA │ │ - SSO into internal web / SAML SP │ │ - AD discovery from the foothold │ └───────────────┬───────────────────────┘ │ ▼ ┌──────────────────────────────────────┐ │ 7. Objective: durable internal access │ │ → reuse creds, persist, expand │ └──────────────────────────────────────┘

From an unauthenticated request to an internal pivot. The decisive move is step 3: a single request never triggers the mixup; concurrency aimed at the real-user login window does.

The junction that matters is step 3. Everything before it is reconnaissance that a careful defender could also perform. The instant the operator generates concurrency aimed at the window when real users are authenticating, the non-deterministic mixup becomes a probability game they can run thousands of times an hour. Step 4, capturing a session that is not theirs, converts the edge appliance from a wall into a door. And because that session was issued by the AAA/Gateway after MFA, the attacker inherits the satisfied MFA: there is no second factor left to ask for. This is the exact property that made CitrixBleed so destructive, reached by a different mechanism.

How this sits in the CitrixBleed lineage

It helps to read CVE-2026-4368 against its family, because the lineage is the reason a defender should take a CVSS-7.7 race more seriously than the number alone suggests. Every one of these reaches authenticated access on the identity boundary; they differ in mechanism and in how you must test for them.

THE CITRIXBLEED LINEAGE — same prize, different mechanism CVE-2023-3519 Unauth RCE on Gateway/AAA. Webshell + AD discovery. (CISA AA23-201A — critical-infra victim.) │ ▼ CVE-2023-4966 "CitrixBleed." Memory overread → live session tokens. MFA + password bypass. (LockBit, CISA AA23-325A.) │ ▼ CVE-2023-6548 Authenticated low-priv management-plane RCE + 6549 (NSIP/CLIP/SNIP reachable) + Gateway/AAA DoS. │ ▼ CVE-2026-3055 "CitrixBleed 3." SAML IdP memory overread. (KEV 2026-03-30. Gate = SAML IdP config.) │ ▼ CVE-2026-4368 Race-condition USER-SESSION MIXUP. Concurrency, not memory read. Gate = Gateway/AAA, build 14.1-66.54. ← single-request probes miss it.

Read the lineage: the mechanism keeps changing (RCE, memory overread, race), but the destination, someone else's authenticated session on the identity boundary, does not.

Two things follow from the lineage. First, on this appliance the destination matters more than the CVSS. A 7.7 race that lands a victim's MFA-satisfied session on the identity boundary is operationally in the same league as the 9-rated memory-read bugs above it, because they all end at the same place. Second, the test surface keeps shifting. CVE-2023-4966 and CVE-2026-3055 (the SAML-IdP-gated "CitrixBleed 3," added to CISA's KEV catalog) are memory-read bugs you test for with a crafted request. CVE-2026-4368 is a race you can only test for with concurrency. A monitoring program tuned to the memory-read family will not detect the session-mixup sibling at all.

A composite real-world walk

A composite, synthesized across validation cases on NetScaler-fronted environments, no single customer. The target is an enterprise that publishes internal applications and virtual desktops to remote staff through a NetScaler Gateway with an AAA virtual server doing SAML-backed authentication.

Step 1 and 2, identify and gate. The operator finds the Gateway login portal and confirms by its page family and NetScaler cookies that it is a Gateway/AAA surface, not an LB-only vserver. They deliberately do not trust the cache header for a version, because they know NS-CACHE-9.3 is a caching signal, not firmware. The role gate (Gateway/AAA, auth surface reachable) is what makes the target in-scope for the mixup class.

Step 3, generate concurrency. Instead of one login probe, the operator issues tightly overlapping request bursts against the authentication endpoint, timed to coincide with the morning login surge when hundreds of real employees are authenticating. The point is volume and overlap: each burst is another roll of the dice on the timing window where the appliance can cross session context.

# Conceptual shape only — overlapping bursts, not one request:
#   fire N near-simultaneous unauth requests, repeat across the
#   real-user login window, and compare each response's session
#   context against the (empty) context we sent.
for window in morning_login_surge:
    responses = fire_concurrent_burst(target, count=N)   # overlapped
    for r in responses:
        if r.session_principal and r.session_principal != MY_PRINCIPAL:
            record_cross_user_leak(r)     # ← the mixup signal

Step 4, capture. Across thousands of attempts, a small fraction of responses come back carrying a session context that is not the operator's: a different principal, a populated authenticated cookie. The appliance handed one of the operator's unauthenticated requests a victim's live session. Because that session was minted post-SAML, post-MFA, the operator now holds an authenticated identity with no second factor left to clear.

Steps 5 through 7, replay and pivot. The operator replays the captured session against the Gateway portal and is logged in as the victim, with their published applications, their VDI entitlements, their internal reach. From that foothold the path is the same one the 2023 advisories documented: enumerate the internal estate, SSO into internal web applications that trust the Gateway's authentication, perform Active Directory discovery, and establish durable access. The edge appliance has been converted from the organization's strongest perimeter control into the attacker's most convenient internal pivot, and the version-scan report on the CISO's desk still says the appliance is up to date, because it was reading a build number, not running a race.

What we observe in customer environments

We are explicit about our visibility: we validate the scoped edge assets a customer flags, and our session-integrity testing is concurrency-based, non-destructive, and stops at proof-of-reachability: we do not exfiltrate real user sessions. With that caveat, the recurring pattern on NetScaler-fronted estates:

The honest read: the session-mixup class is under-tested precisely because it requires a test most tooling cannot perform, and the appliance it affects is the one where a stolen session does the most damage.

What to do about it

The fix for CVE-2026-4368 is concrete and advisory-backed, but it is more than "apply the patch." Treat it with the full CitrixBleed-family discipline, because the destination is the same.

NetScaler session-integrity contract: what actually closes it

A version scan reads a build number. A race condition is won with concurrency. If your probe fires one request at a time, it will tell you the appliance is clean while the attacker is logging in as your CFO.

The cheapest high-value move for a CISO this week: pull the exact build of every NetScaler node, not the primary alone, from authenticated show version output, gate it against CTX696300, and confirm whether the post-upgrade session-termination step was actually performed and documented. Those checks, done honestly, separate "we patched it" from "we closed it."

How Celvex catches this

Find. Prove. Fix. Verify.

Find

We fingerprint Gateway/AAA role from page family and cookies, never a banner version, and run concurrency-based session-integrity probes that look for cross-user context leaks, the signal a single-request scanner cannot produce.

Prove

A confirmed mixup ships a Proof Capsule documenting the reachable role gate, the concurrency pattern, and the cross-user leak observed, all non-destructively, stopping at proof-of-reachability, never exfiltrating real user sessions.

Fix

The Capsule's remediation block names the CTX696300 fixed build per node and the mandatory post-upgrade session termination, scoped to the customer's actual HA/cluster/DR topology.

Verify

After the upgrade and session purge, we re-run the concurrency probe. The cross-user leak no longer reproduces, and the dashboard records the verified-fix event for the auditor record.

Where we sit honestly: our edge-appliance testing models the session-integrity class with concurrency, which is the only way to observe a race-condition mixup, and we report the role gate and build evidence rather than a banner guess. We do not weaponize against live user sessions and we do not claim a version string is proof of exposure. We do claim to test for the sibling that single-request scanning structurally cannot see, and to verify the fix with the same concurrency that found it.

Bottom line

CitrixBleed taught a generation of defenders that a session bug on a NetScaler appliance is a building key with the MFA lock pre-opened. CVE-2026-4368 reaches the same destination by a quieter mechanism: not a memory read but a race, won with concurrency aimed at the moment real users authenticate. It is gated on a specific build and the Gateway/AAA role, not on anything a banner reveals, and a probe that fires one request at a time will report your appliance clean while the appliance is busy handing your employees' sessions to an attacker. Close it with the full family discipline of patching every node, terminating sessions, isolating the management plane, and testing with concurrency, then verify the race no longer reproduces.

Verifiable security. Find it. Prove it. Fix it. Verify the fix held. That is what we ship.

Sources

Is your NetScaler clean, or just clean on a banner?

Free Exposure Check, no signup required. We fingerprint the Gateway/AAA role and run concurrency-based session-integrity probes that single-request scanners cannot, then ship a Proof Capsule for the highest-confidence finding.

Run a Free Scan →