A patch released in February is now the engine of one of the larger website-poisoning campaigns of the year. CVE-2026-26980 is an unauthenticated SQL injection in Ghost CMS’s Content API, rated CVSS 9.4 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:L, CWE-89). XLab threat intelligence at Qianxin has confirmed it has been weaponized against more than 700 domains — university portals at Harvard, Oxford, and Auburn, AI and SaaS vendors, fintech firms, media outlets, security blogs, and DuckDuckGo among them — to seed ClickFix malware lures.
What happened
Ghost quietly fixed the bug in version 6.19.1 on February 19, 2026. Every internet-facing Ghost install running 3.24.0 through 6.19.0 remained exploitable with a single crafted HTTP request. By May 7, XLab had detected the first poisoned site, and the investigation found an attack that had already been fully automated: a bulk scanner, automatic key extraction, bulk article injection, and dynamic payload distribution. The patch gap — disclosed flaw, available fix, slow installed base — is the entire story.
Technical details
The defect lives in slug-filter-order.js inside the Content API input serializer. The function slugFilterOrder(table, filter) parses slug:[a,b,c] expressions out of an NQL (Ghost Query Language) filter and builds a raw SQL CASE WHEN ... END ASC fragment used in an ORDER BY clause. Attacker-controlled slug values are concatenated straight into that fragment via JavaScript string interpolation — no sanitization, no query binding.
Reaching the injection point means defeating Ghost’s NQL parser, and the bug is a grammar mismatch. NQL accepts a quoted STRING token as a single, valid slug value. But slugFilterOrder then runs a naive .split(',') on the bracket contents, slicing right through the NQL string and producing multiple synthetic “slug” fragments. An attacker bridges those fragments back together with SQL string concatenation into one attacker-controlled scalar expression inside ORDER BY.
The result: a single unauthenticated GET request carrying a crafted filter=slug:[...] (or order=slug:[...]) parameter yields a time-based blind oracle. Arbitrary database values come out one character at a time — including admin credentials, bcrypt password hashes, session secrets, and, critically, Admin API keys.
Impact assessment
This is information disclosure that escalates to full content control. The campaign chains it cleanly: exploit the SQLi to extract the site’s Admin API key, then use that key — legitimately, through the API — to rewrite published articles. The injected payload is a lightweight JavaScript loader that pulls a second-stage cloaking script. That script fingerprints each visitor, and qualifying targets are shown a fake Cloudflare verification prompt loaded in an iframe over the article. That is the ClickFix lure. Observed payloads include DLL loaders, JavaScript droppers, and an Electron-based sample named UtilifySetup.exe.
For a self-hosted Ghost operator the blast radius is your readers’ machines and your own credential store at once.
Mitigation — do this now
Upgrade to Ghost 6.19.1 or later immediately; the fix replaces the vulnerable string interpolation with parameterized queries. Patching alone is not enough if you were exposed:
- Assume your Admin API key and Content API key are stolen — rotate both.
- Rotate the session secret, force-invalidate all sessions, and reset admin passwords (the bcrypt hashes may have been exfiltrated and are now offline-crackable).
- Audit every published post for injected
<script>tags or unfamiliar loader URLs. - Grep Content API access logs for
filter=slug:[andorder=slug:[request patterns to scope the intrusion window. - If you cannot patch instantly, have your WAF block
filter/orderparameters containing bracketed, comma-separatedslugvalues as an interim measure.
Self-hosted CMS installs are infrastructure. Treat the version number on your Ghost box the way you treat the kernel on your hosts.
References
- The Hacker News — Ghost CMS CVE-2026-26980 Exploited to Hijack 700+ Sites
- BleepingComputer — Ghost CMS SQL injection flaw exploited in large-scale ClickFix campaign
- SonicWall — Ghost CMS Content API Blind SQL Injection (CVE-2026-26980)
- SecurityWeek — Ghost CMS Vulnerability Exploited to Hack Over 700 Websites
- NVD — CVE-2026-26980 Detail