Two ServiceNow sandboxes that shared one JavaScript scope
On Friday July 18 Defused researchers started catching sandbox escape payloads against /assessment_thanks.do on unpatched ServiceNow AI Platform instances. ServiceNow had shipped the fix five days earlier on July 13 and Searchlight Cyber had published its technical writeup on the same date. CVE-2026-6875 rates a CVSS of 9.5. What it actually turns into is a jump host from the public internet into the customer network through the MID Server that sits behind the instance. The advisory is KB3137947, and by July 20 BleepingComputer and Help Net Security both had active in-the-wild abuse on record. Cloud tenants received a platform mitigation within 24 hours of the April 1 vendor report; the exposed population today is self-hosted plus any cloud tenant still off the fixed patch train.
The pre-auth query that reads user input as JavaScript
The reachable sink is /assessment_thanks.do, an endpoint served without authentication so a survey respondent finishing an assessment can hit it from a link in an email. It takes a parameter named sysparm_assessable_type and hands the value straight into a GlideRecord query as an addQuery argument. The choice that reads badly in hindsight is what GlideRecord does with values beginning with the literal string javascript:: it strips the prefix, treats the remainder as a JavaScript expression, evaluates it, and uses the return value as the query argument. Anyone with a URL bar has arbitrary JavaScript execution on the server before they touch a login page.
The JavaScript does not run in the general application context. It runs inside an inner sandbox that ServiceNow layers on top of the underlying Rhino engine, and that inner sandbox blocks the primitives an attacker would normally reach for: Packages, java, reflective class access, and direct calls into shell utilities. Inside the inner sandbox, an attacker holds arithmetic, string handling, and a very small standard library. The whole security story of the pre-auth surface was built on the assumption that no one could climb out.
Why gs.include() reaches the less restricted world
The Assetnote team on the Searchlight Cyber research desk found the seam. Not every function inside the inner sandbox stays inside the inner sandbox. gs.include() loads a named script library into the platform by handing the library's source code to the outer, general-purpose execution context. That outer context has the Rhino primitives the inner sandbox denied. Reading arbitrary tables, creating administrator accounts, and running shell commands on connected MID Server proxies all live there.
If the loaded library were executed in complete isolation from the inner sandbox, the escape would end and the platform would still be safe. That is not what happens. The two contexts share one JavaScript global scope. When the inner sandbox mutates a property on the shared globals, that mutation is visible to the library code the outer context is about to run. The attacker writes a small script that overrides a global helper function the library will call, then triggers gs.include() on a library that calls it. The library runs unsandboxed, invokes the overridden global, and the attacker's replacement executes with full outer-context privileges. From there it is a short walk to Packages.java.lang.Runtime.exec() and a shell.
The globals both sandboxes edit at the same time
The specific gadget can be many different things; what matters is the shape. Any function or property on the shared global scope that a loaded library invokes becomes attacker-controlled the moment the inner sandbox reassigns it. Once the attacker holds one outer-context primitive, they hold the whole instance. That is why Defused noted the in-the-wild payloads on July 18 were reaching the same code execution primitive as the Assetnote PoC through a different escape gadget. Attackers found their own overrideable globals rather than copying the ones the researchers documented. The class is generic; the specific hook is disposable.
/assessment_thanks.do because that is the pre-auth sink for the JavaScript evaluation. The sandbox escape past that point is a class of bugs, not a single one, so the payloads diverge inside the same endpoint.
Why a CVSS-first queue mis-ranks it
The mis-ranking is not in the CVSS itself; a 9.5 unauthenticated RCE draws attention on its own. It is in what CVSS does not encode. A ServiceNow AI Platform instance is rarely just an instance. It is the front door to a MID Server, and the MID Server sits inside the customer network with credentials into CMDB integrations, cloud accounts, ticketing back ends, and everything the platform automates against. A scanner queue treats the instance as one system to patch. Reality treats it as a jump host with a saved SSH agent onto a directory of production integrations. An internet-facing production tenant tunneling into Active Directory does not deserve the same queue slot as an isolated developer instance running the same version.
TRIS on CVE-2026-6875, layer by layer
TRIS is CVEasy AI's Threat and Risk Intelligence Scoring engine, and it decides this finding across four layers.
Exploit status. Public PoC from the Searchlight Cyber writeup on the patch date and confirmed in-the-wild abuse from Defused on July 19, with variants reaching the same execution primitive through independent sandbox escape gadgets. That combination puts the exploit layer in the top band; a proven PoC alone is not the same claim as confirmed in-the-wild abuse, and the July 19 telemetry is the escalation.
Instance exposure. Public reachability of /assessment_thanks.do is the switch between top band ACT and something several bands lower. An internet-facing instance sits in ACT. An instance behind a VPN with a country-restricted allowlist and no exposed MID Server tunnel drops well below that on the same unpatched version.
Lateral value. MID Server connectivity into production is the multiplier. If the MID Server holds service account credentials for the change management system, the CMDB integration into cloud accounts, or a scheduled sync into Active Directory, the finding stays at ACT because a compromised instance becomes a compromised integration.
Data sensitivity. ServiceNow tables hold incident payloads, employee records, and encryption keys used by workflows. Instances hosting regulated data land in the top band on this layer alone, even before the MID Server pivot is considered.
The same CVE score resolves to very different real risk once those layers are honest, and a reachable dev instance is not the same finding as a reachable production tenant fronting your MID Server. TRIS names the distinction and scores each instance separately.
The July 13 patch, Guarded Script, and what to hunt in your logs
Apply the July 13 hotfix per KB3137947. The fixed release trains named in the advisory are Brazil EA and Brazil GA, Australia Patch 2, Zurich Patch 7b and Patch 9, and Yokohama Patch 12 Hot Fix 1b and Patch 13. The same patch enables Guarded Script (KB2944435), a hardening feature that limits the inner sandbox to single simple expressions: variable declarations, control flow, function declarations, assignment operators, and multi-statement scripts are all rejected, which closes the shape of gadget the current exploit relies on. Enable Guarded Script after you patch. Do not enable it as a substitute for patching.
For log review, pull every access to /assessment_thanks.do since July 13 whose sysparm_assessable_type value starts javascript:, or is unusually long against legitimate assessment types on your instance. Correlate any hit to outbound connections from the MID Server host in the same window. Audit sys_user for admin-role accounts created since July 13, and sys_script_include for any include modified outside change process in the same window. Rotate MID Server credentials and any secret record accessible from the instance if you cannot cleanly rule out execution. Cloud tenants that received the April platform mitigation still need to confirm the July 13 patch train applies to their instance before the finding closes.
How CVEasy AI surfaces CVE-2026-6875
CVEasy AI, the number one local-first CTEM platform, ingests the ServiceNow advisory, the Searchlight Cyber writeup, and the Defused telemetry, then runs TRIS against the ServiceNow instances in your inventory on your own hardware. Every instance is scored on its own for exposure, lateral value into MID Server tunnels, and data sensitivity, so the queue lists your one internet-exposed production tenant with a live MID Server ahead of six identical dev instances that share nothing with the internal network. The remediation workflow points at KB3137947, the specific fixed patch train for the version you run, the log queries against your access logs, and the credentials your MID Server holds. Your ServiceNow inventory, credential records, and log data stay on your hardware.
Sources: Searchlight Cyber, ServiceNow KB3137947, BleepingComputer, Help Net Security, The Hacker News, Defused telemetry, SecurityWeek, Assetnote.