The 33 Day Blind Spot: How CVE-2026-110447 Outran Its Own CVE
The code fix landed on 9 September. The first attack hit on 10 September. The release shipped on 11 September. The CVE that would tell defenders any of this mattered did not arrive until 14 October.
What Happened?
CVE-2026-110447 is an unauthenticated OS command injection in proxy.php, inside Nextcloud’s Collabora Online Built-in CODE Server app. It scores 9.2 on CVSS v4.
The quirk is timing. The bug only triggers when the local CODE server isn’t running, so a restart or crash exposes it.
Operator-posted access logs show attack requests from 10 September, a day after the fix was committed publicly and a day before release 26.4.303 shipped it. The advisory and CVE followed on 14 October. CISA added it to the Known Exploited Vulnerabilities catalog on 23 October, with remediation due 26 October.
What’s the Impact?
Operators found PHP web shells in the app directory. On one host, the intruder ran discovery commands for password manager files and crypto wallets. An upgrade shuts the bug but leaves an earlier shell in place. Disabling it left the path open. One operator alleged ransomware. Nobody confirmed it.
Collabora Built-in CODE Server for Nextcloud
Indicators published by server operators who found this activity in their own logs, plus the request characteristics named in the public reports. Scope: Nextcloud installs running the richdocumentscode app below version 26.4.303.
Network and HTTP
| Type | Indicator | Context |
|---|---|---|
| Source IPv4 | 139.28.18.122 | Requests logged 10 and 11 September 2026 |
| Source IPv4 | 89.38.98.50 | Request logged 14 September 2026 |
| Callback domain | webhook.site | Beacon target for host fingerprint data |
| Callback path ID | 45060ed4-de0b-4119-8f0d-2a2776bbd413 | Unique collector ID in the 10 September payload |
| Callback path ID | 774cf5e1-b5a4-4174-a1ad-0241861029a2 | Reused across 11 and 14 September payloads |
| User agent | Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/126.0 | Static across observed requests. Weak on its own |
Request characteristics
| Element | Pattern | Context |
|---|---|---|
| Target endpoint | /apps/richdocumentscode/proxy.php?status | The injection point. Also reached on a disabled app |
| Encoded traversal | %2e%2e | Used in later requests in place of a literal traversal |
| Command substitution | $( / %24%28 | Shell substitution inside the request path |
| Space obfuscation | ${IFS} | Avoids literal whitespace in the injected command |
| Decode and execute | base64${IFS}-d|sh | Terminal stage of the injected chain |
| Follow up probe | ?c=id | Confirms the dropped file is live |
Host and file
| Type | Indicator | Context |
|---|---|---|
| File path pattern | apps/richdocumentscode/shx*.php | Primary dropped file naming pattern |
| File path pattern | apps/richdocumentscode/shrf*.php | Variant seen in the earliest report |
| Observed filenames | shrf4645.php, shxa35d0.php, shx5cf91.php, shxd33ce.php, shxf4645.php, shx13a86.php, shx56367.php | Names are randomised per request. Match the pattern, not the list |
| SHA-256 | 4b9fbd0663fbfd6028fc216ed18e0d6ef3ae498a7fdc97083e4b0ce3cec40562 | One recovered dropped file |
| File behaviour | A single line PHP file that reads one HTTP GET parameter and passes it to a shell execution function, returning output in the response. Roughly 70 bytes. | Any such file in the app tree is not legitimate |
| Process anomaly | remote_font_config.url | A CODE AppImage or coolwsd process whose font config argument carries shell substitution |
| Integrity signal | Nextcloud app integrity check failing for richdocumentscode | How at least one operator first noticed |
Post access discovery targets
| Category | Strings searched on one host |
|---|---|
| Password manager data | *.kdbx, bitwarden, 1password |
| Wallet and key material | wallet.dat, keystore.json, .bitcoin, .electrum, .monero, .ethereum |
Reviewed requests did not show archiving or upload commands, so exfiltration is not confirmed. A shell running as the web server account can still read anything that account can read, so treat credentials and secrets reachable by that account as potentially exposed.
Hunting commands
Log paths and the Nextcloud root differ per install. A hit on the request pattern alone means an attempt. A dropped file, an integrity failure or an anomalous process means it worked, and the host should be handled as compromised rather than simply patched.
Why 33 Days Matters
Scanners key on CVE IDs. For 33 days after the fix shipped, no ID existed, so no one found it or opened a ticket. An October 2026 study of 18,594 open-source CVEs found the median gap between a public code fix and CVE publication was 5.1 days in January 2026, rising to 39.2 days by August. That is one study and should be read as directional, but the shape matches what happened here.
The pattern keeps repeating. We have seen flaws exploited before a patch was released, and cases where CISA confirms active exploitation long after the code was quietly fixed. Severity scores told a mixed story too. This one scored 9.2, and its exploit probability score sat near 1.2%. The web shells were real anyway.
How to Avoid This
- Upgrade richdocumentscode to 26.4.303 or later, or remove the app outright. On Nextcloud 29 and older, upgrade Nextcloud or drop the app.
- Treat a disabled app as still installed and still reachable through proxy.php.
- Search the app directory for PHP files matching the shx and shrf naming pattern, and rotate any secret the web server account could read if you find one.
- Check egress logs for callbacks to webhook.site from your web server.
- Watch vendor release feeds and commit activity alongside CVE identifiers.
Switching the app off is not remediation.
The vulnerable request still reaches proxy.php on a disabled app, and the flaw fires precisely when the local CODE server is down. Find the state you are actually in.
Paths vary by install. Conditions drawn from the vendor advisory for CVE-2026-110447 and operator reports on the project issue tracker.
Find It Before the Catalog Does
Scanners wait for an ID. For 33 days, no ID existed to wait for, while anyone reading the public commit had everything they needed. Secure.com closes that gap by starting from what is reachable on your network today.
- The Red Teammate attacks your approved scope and confirms which exposures actually work against you, so the fix list is ranked by evidence.
- Asset and app inventory surfaces where a package like this is installed, including instances switched off but never removed.
- A confirmed finding becomes governed defensive work: a patch workflow, a config change, a retest, with human approval on anything consequential.
- Record every action, approval,, and outcome so an auditor can see what was found, who signed it off, and when it closed.
- Start with one teammate, above the stack you already own. Attack. Harden. Prove. Repeat.