core-jmp core-jmpdeath of core jump

Breaking ONLYOFFICE in 3 steps: OnlyShells vulnerability chain

Technical breakdown of OnlyShells — a five-vulnerability chain in ONLYOFFICE Desktop Editors combining zero-click XSS, a Chromium V8 RCE, and an update-service LPE to achieve remote code execution as NT AUTHORITYSYSTEM when a victim opens a crafted document.

oxfemale July 22, 2026 11 min read 215 reads
Export PDF
Breaking ONLYOFFICE in 3 steps: OnlyShells vulnerability chain
Original text: “Breaking ONLYOFFICE in 3 steps: OnlyShells vulnerability chain”BI.ZONE Vulnerability Research team, BI.ZONE (July 21, 2026). Code, CVE metadata, figures and the demonstration video below are reproduced with attribution captions.

Executive Summary

OnlyShells is a chain of five vulnerabilities discovered in ONLYOFFICE Desktop Editors during a fall 2025 security assessment. Chained together, these flaws allow an attacker to obtain a shell running as NT AUTHORITY\SYSTEM the moment a victim opens a specially crafted document—no further interaction required. The chain stitches together three distinct problem classes: a zero-click cross-site scripting (XSS) flaw that executes JavaScript on document open, a critical remote code execution (RCE) bug in the outdated Chromium V8 engine bundled with the editor, and a local privilege escalation (LPE) in the application’s SYSTEM-level update service.

The core weakness is architectural: ONLYOFFICE Desktop Editors is a Chromium-based application built on the Chromium Embedded Framework, ships an engine version that went out of support in 2023, runs without browser sandboxing, and installs a helper service with the highest privileges on the system. This article walks through each link of the chain—the three XSS vulnerabilities that establish a JavaScript foothold, the V8 type-confusion bug that turns that foothold into native code execution, and the update-service file-deletion primitive that escalates to SYSTEM. The vendor has fixed the issues in ONLYOFFICE Desktop Editors 9.3.0.

Overview

In the fall of 2025, the BI.ZONE Vulnerability Research team assessed the security of ONLYOFFICE Desktop Editors and uncovered five vulnerabilities that together form what they named the OnlyShells chain. The chain lets an attacker land an NT AUTHORITY\SYSTEM shell after a victim simply opens a booby-trapped document. The sections below dig into the technical detail of each individual vulnerability.

Attack Surface

ONLYOFFICE Desktop Editors is built on the Chromium Embedded Framework (CEF), making it a Chromium-based application. Critically, it runs without browser sandboxing and ships Chromium 109.0.5414.120—a build that was already outdated back in 2023. The editor also bundles an update service that runs with NT AUTHORITY\SYSTEM privileges, presenting an attractive target for privilege escalation.

A second large attack surface exists in the parsers for various file formats, many of which are implemented in memory-unsafe languages. However, even a strong exploitation primitive there is usually held back by the one-shot nature of the attack: it cannot adapt on the fly to a victim’s system mitigations such as PIE and ASLR. With that constraint in mind, the researchers proposed the following three-step chain:

  1. XSS exploitation leading to arbitrary JavaScript code execution.
  2. Renderer flaw exploitation.
  3. Update service flaw exploitation for privilege escalation.

Let us examine the vulnerabilities that make up each step.

XSS Vulnerabilities

CVE-2025-68917

SeverityMedium
CVSS score6.4
CVSS vector stringCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N
Privileges requiredNone
Source: original article.

Description. When a victim clicks the button to edit a comment, the page automatically builds an editing field roughly of the form <textarea>{{USER_INPUT}}</textarea>. The USER_INPUT portion is not escaped, so an attacker can smuggle a payload into a comment and execute arbitrary JavaScript the instant the victim clicks Edit comment.

Exploitation example:

  1. An attacker creates a malicious comment similar to </textarea><script>{{JavaScript code}}</script><textarea>.
  2. When the victim edits the comment, the malicious script executes.
Exploitation example: Hello World serves as PoC
Exploitation example: <h1>Hello World</h1> serves as PoC. Source: original article.
Page after payload activation: Hello World appears on screen
Page after payload activation: Hello World appears on screen. Source: original article.

CVE-2025-68935

SeverityMedium
CVSS score6.4
CVSS vector stringCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N
Privileges requiredNone
Source: original article.

Description. Editing list parameters opens a modal window that offers a list-type selection option.

List parameters modal window
List parameters modal window. Source: original article.

The available list types include fonts whose names are inserted into the style attribute without being escaped.

DOM tree fragment. Font set via style
DOM tree fragment. Font set via style. Source: original article.

Malicious JavaScript embedded in a font name executes when the List parameters modal window opens.

Exploitation example:

  1. An attacker adds a custom list type to the document. The font name contains ;"><script>{{JavaScript code}}</script>.
  2. When the victim opens the List parameters window, the script executes.
DOM tree fragment after injecting payload into font name. Adwaita Mono injected
DOM tree fragment after injecting payload into font name. Adwaita Mono injected. Source: original article.
List parameters modal window after attack
List parameters modal window after attack. Source: original article.

CVE-2025-68936

SeverityMedium
CVSS score6.4
CVSS vector stringCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N
Privileges requiredNone
Source: original article.

This zero-click XSS vulnerability is the most dangerous of the three—it triggers on document opening.

Description. Document theme names in the drop-down list are not escaped. An attacker can craft a document with a theme whose name carries a payload. The vulnerable drop-down list is integrated into the page DOM when the file opens, so the XSS payload runs automatically on document open—without any user interaction.

Exploitation example:

  1. An attacker injects a theme with a payload similar to <script><{{JavaScript code}}</script>.
  2. JavaScript code executes automatically when the document is opened.
Hello World payload injected into page serves as PoC
<h1>Hello World</h1> payload injected into page serves as PoC. Source: original article.

Any of the three XSS vulnerabilities enables arbitrary JavaScript code execution. However, CVE-2025-68936 is the most dangerous—the malicious code runs upon document opening without any further user interaction.

RCE: Chromium Web Engine Compromise

CVE-2023-2033

SeverityCritical
CVSS score9.3
CVSS vector stringCVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
Privileges requiredNone
Source: original article.

Description. ONLYOFFICE Desktop Editors uses Chromium Embedded Framework 109.0.5414.120, which contains a JavaScript V8 engine affected by CVE-2023-2033. Exploiting any one of the XSS vulnerabilities above turns arbitrary JavaScript into full remote code execution. Only the key aspects of CVE-2023-2033 are covered here, since the bug merits an article of its own.

The vulnerability lives in Turbofan, V8’s JIT compiler. A compilation error lets an attacker obtain the hole value—an internal representation of an empty slot in JavaScript arrays. Once this value is in hand, the attacker can abuse type confusion with array indexes to achieve RCE.

Exploitation example:

  1. Obtain the V8 internal hole value.
  2. Abuse type confusion to substitute hole with array indexes, enabling out-of-bound writes.
  3. Retrieve the addrof, fakeobj, sandbox_read, and sandbox_write primitives to read and write arbitrary values anywhere inside the V8 sandbox heap.
  4. Generate intermediate shellcode via JIT spraying.
  5. Use the acquired primitives to replace a JavaScript function’s reference with the generated shellcode.
  6. Prepare a payload and transfer execution to it via the intermediate shellcode.

At this point arbitrary code can run on the machine whenever a specially crafted file is opened. That is already a serious impact—but the chain goes further and attempts privilege escalation.

LPE: Update Service Exploitation

CVE-2026-41030

SeverityMedium
CVSS score6.2
CVSS vector stringCVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Privileges requiredUnprivileged Windows user
Source: original article.

Description. To carry out update tasks, the service exposes a local port for communication over UDP. One of those tasks clears the temporary directory by deleting every file whose name begins with a string supplied over the protocol, searching recursively through nested directories. Because the matched files are not validated before deletion, an attacker can point the routine at a symbolic link (a junction) and obtain an arbitrary-file-deletion primitive running as NT AUTHORITY\SYSTEM.

ONLYOFFICE vulnerable code segment:

// csvcmanager.cpp (project:desktop-apps)
void CSvcManager::clearTempFiles(const tstring &prefix, const tstring &except)
{
    m_future_clear = std::async(std::launch::async, [=]() {
#ifdef _WIN32
        if (NS_File::fileExists(NS_File::appPath() + RESTART_BATCH))
            NS_File::removeFile(NS_File::appPath() + RESTART_BATCH);
#endif
        tstring _error;
        list<tstring> filesList;
        if (!NS_File::GetFilesList(NS_File::tempPath(), &filesList, _error, true)) {
            NS_Logger::WriteLog(DEFAULT_ERROR_MESSAGE + _T(" ") + _error);
            return;
        } // returning files list to delete, big recursive cycle to find all files that matches pattern
        for (auto &filePath : filesList) {
#ifdef _WIN32
            if (PathMatchSpec(filePath.c_str(), L"*.json") || PathMatchSpec(filePath.c_str(), ARCHIVE_PATTERN)
                || PathMatchSpec(filePath.c_str(), L"*.msi") || PathMatchSpec(filePath.c_str(), L"*.exe")) {
#else
            if (fnmatch("*.json", filePath.c_str(), 0) == 0 || fnmatch(ARCHIVE_PATTERN, filePath.c_str(), 0) == 0) {
#endif
                tstring lcFilePath(filePath);
                std::transform(lcFilePath.begin(), lcFilePath.end(), lcFilePath.begin(), ::tolower);
                if (lcFilePath.find(prefix) != tstring::npos && filePath != except)
                    NS_File::removeFile(filePath); // deleting files
            }
        }
        tstring updPath = NS_File::parentPath(NS_File::appPath()) + UPDATE_PATH;
        if (except.empty() && NS_File::dirExists(updPath))
            NS_File::removeDirRecursively(updPath);
    });
}

Exploitation example:

  1. Start the installation of a specially crafted MSI package.
  2. Create 0000\prefix_filename.json and 0001\prefix_filename.json in the temporary directory.
  3. Protect 0000\prefix_filename.json from deletion.
  4. Send a package with a command to clean up the temporary directory using the prefix argument. During request processing, the update service collects the list of files to delete—including 0000\prefix_filename.json and 0001\prefix_filename.json. Once the list is gathered, the service tries to delete 0000\prefix_filename.json, but the deletion protection makes the DeleteFile WinAPI call fail until the protection is lifted.
  5. Replace 0001\prefix_filename.json with a symbolic link to Config.Msi:$INDEX_ALLOCATION while the service is still waiting on the deletion of 0000\prefix_filename.json.
  6. Disable the 0000\prefix_filename.json deletion protection. The update service continues processing the list, which still contains 0001\prefix_filename.json. Because of the symbolic-link substitution, Config.Msi:$INDEX_ALLOCATION is deleted instead, which also removes the Config.Msi directory.
  7. Create a Config.Msi directory, keep its handle, and subscribe to write operations for files inside it.
  8. Restart the installation of the crafted MSI package. During installation, the directory permissions are overwritten back to the original ones (NT AUTHORITY\SYSTEM).
  9. Detect the rollback script record.
  10. Reclaim rights to modify Config.Msi as a non-privileged user. This is possible because we hold an open handle with rights to modify the DACL.
  11. Replace the rollback script with a malicious one that, for example, establishes a reverse shell connection to an arbitrary server.
  12. Cancel the installation, which triggers the malicious rollback script to execute under NT AUTHORITY\SYSTEM.

Full Exploitation Cycle

OnlyShells chain: full exploitation cycle. Source: original article.

Key Takeaways

  • OnlyShells chains five vulnerabilities in ONLYOFFICE Desktop Editors into a single document-open-to-SYSTEM attack, with CVE-2025-68936, CVE-2023-2033, and CVE-2026-41030 forming the minimal path.
  • The most dangerous link is a zero-click XSS (CVE-2025-68936): an unescaped document theme name executes JavaScript automatically the moment the file is opened, requiring no victim interaction.
  • The bundled Chromium Embedded Framework 109.0.5414.120 carries the critical V8 Turbofan type-confusion bug CVE-2023-2033, turning JavaScript execution into native RCE inside an unsandboxed process.
  • The SYSTEM-privileged update service exposes a UDP-controlled temp-cleanup task that deletes unvalidated files, yielding an arbitrary-delete primitive that is escalated to code execution via a Config.Msi rollback-script hijack.
  • Running an out-of-support Chromium build without sandboxing, combined with a high-privilege helper service, is the structural root cause that makes the whole chain viable.
  • The vendor fixed the issues in ONLYOFFICE Desktop Editors 9.3.0.

Defensive Recommendations

  • Update immediately: upgrade ONLYOFFICE Desktop Editors to version 9.3.0 or later, which remediates the full OnlyShells chain.
  • Treat documents as untrusted input: open documents from unknown or external sources in isolated environments (disposable VMs, sandboxes) given the zero-click nature of CVE-2025-68936.
  • Monitor the update service: alert on unexpected UDP traffic to the update service’s local port and on temp-directory file churn that resembles junction/symlink swapping.
  • Watch Config.Msi tampering: detect deletion and recreation of the Config.Msi directory and rollback-script modification during MSI transactions—classic signals of this LPE technique.
  • Constrain the editor process: apply application allow-listing and restrict child-process spawning from the editor to limit post-exploitation, since the renderer runs unsandboxed.
  • Deploy behavioural detection: endpoint detection and response tooling that flags SYSTEM-level shells and reverse-shell activity spawned from document workflows catches the post-exploitation stage even if the initial bug is unpatched.
  • Inventory embedded engines: track the Chromium/CEF versions shipped inside desktop applications; out-of-support engines like 109.x re-expose long-patched browser CVEs.

Conclusion

CVE-2025-68936, CVE-2023-2033, and CVE-2026-41030 together comprise the OnlyShells chain, which enables arbitrary code execution with SYSTEM privileges when a specially crafted file is opened. To defend against OnlyShells, update ONLYOFFICE Desktop Editors to version 9.3.0. According to the original authors, BI.ZONE EDR correctly detects the post-exploitation activity that results from the chain. The case is a reminder that embedding an out-of-support browser engine and pairing it with a high-privilege update service can quietly reconstitute a full document-open-to-SYSTEM attack path.

Original text: “Breaking ONLYOFFICE in 3 steps: OnlyShells vulnerability chain” by the BI.ZONE Vulnerability Research team at BI.ZONE.

oxfemale Vulnerability research, reverse engineering, and exploit development.
// Discussion