TYPO3-EXT-SA-2026-013 (CVE-2026-46725): Insecure Deserialization in “Content Element Selector” (ceselector) — Unauthenticated RCE, Fixed in 6.0.1/5.0.1/4.0.2/3.0.3
On 19 May 2026 the TYPO3 Security Team published TYPO3-EXT-SA-2026-013: CVE-2026-46725 (CVSS 4.0, Critical) in the third-party extension “Content Element Selector” (Composer package mmc/ceselector). The extension passes a client-controllable cookie straight into PHP's unserialize() without validation. On content elements configured with “Persistent Mode: Static”, this enables PHP object injection — and, given a suitable gadget chain in the environment, unauthenticated remote code execution with no login required. Affected are ceselector versions up to 6.0.0, up to 5.0.0, 4.0.0 through 4.0.1, and up to 3.0.2. Fix: update to 6.0.1, 5.0.1, 4.0.2, or 3.0.3, depending on the version line in use. A public detection template with a full example payload already circulates for the vulnerable configuration.
TL;DR — 90 seconds
- Affected?
The TYPO3 third-party extension “Content Element Selector” (
mmc/ceselector) in versions ≤6.0.0, ≤5.0.0, 4.0.0–4.0.1, and ≤3.0.2 — and only content elements configured with “Persistent Mode: Static”.- Risk?
CVSS 4.0 Critical (AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H). The extension passes a cookie straight into
unserialize()without validation. That enables PHP object injection; a public detection template already demonstrates a working gadget chain through Monolog classes that are available via Composer on virtually every TYPO3 instance — i.e. unauthenticated remote code execution.- Immediate action?
composer require mmc/ceselector:"^6.0.1"(or the matching minor version for your line). Without an immediate update: move every content element using ceselector off “Persistent Mode: Static” to a different persistence mode, or disable the extension.- Recommendation?
If you run ceselector with Persistent Mode: Static in production and publicly reachable, patch today — that's exactly the configuration for which a public detection/exploit template already circulates.
- Criticality?
critical — unauthenticated, reachable over the network, full compromise of confidentiality, integrity and availability possible per the CVSS vector, public detection template available.
What is the problem?
“Content Element Selector” (mmc/ceselector) is a third-party TYPO3 extension that gives editors an extended selection dialog for content elements. One configuration mode of the affected content element is called “Persistent Mode: Static” — in this mode the extension keeps selection/state information in a cookie that is evaluated on every request.
According to the TYPO3 Security Team (TYPO3-EXT-SA-2026-013, CWE-502), the extension reads this cookie value and passes it directly into PHP's unserialize() — without validation, without an allowlist of permitted classes (no allowed_classes parameter), without falling back to a safer format such as JSON. Because PHP's unserialize() can instantiate arbitrary objects whose constructors and magic methods (__wakeup, __destruct, __toString, among others) run automatically during deserialization, this creates a classic PHP object injection vulnerability: an attacker can instantiate any class available in the autoloader by manipulating the cookie value.
Whether this actually turns into code execution depends on whether a so-called gadget chain is available — a chain of classes whose interaction triggers a dangerous side effect during deserialization (writing a file, executing a command, SSRF). The publicly available detection template for this vulnerability demonstrates exactly such a chain via Monolog\Handler\GroupHandler and Monolog\Handler\BufferHandler, whose processor configuration is chained through to a call of PHP's system(). Monolog is present as a dependency in nearly every TYPO3 and Symfony-based installation — which makes this vulnerability not just theoretical but practically exploitable, without authentication, on most affected instances.
Who is affected?
| Affected | Not affected | Conditions |
|---|---|---|
mmc/ceselector ≤ 6.0.0 | ceselector ≥ 6.0.1 | Content element must be configured with “Persistent Mode: Static” |
mmc/ceselector ≤ 5.0.0 | ceselector ≥ 5.0.1 | A suitable gadget-chain class (e.g. Monolog) must be available in the autoloader — the case on most TYPO3 installations |
mmc/ceselector 4.0.0–4.0.1 | ceselector ≥ 4.0.2 | The instance must be reachable unauthenticated (frontend) — the default case for public content elements |
mmc/ceselector ≤ 3.0.2 | ceselector ≥ 3.0.3 | — |
If ceselector is in use but no content element is configured with “Persistent Mode: Static”, there is no risk from this specific attack path — updating to the patched version is still recommended, since the configuration can be changed at any time and the extension itself would still deserialize without validation.
Impact
The CVSS 4.0 vector (AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H) rates the impact as complete: reachable over the network, low attack complexity, no user interaction, no authentication required, full impact on confidentiality, integrity and availability. In practice, successful exploitation via an available gadget chain means arbitrary code runs with the privileges of the PHP process — typical consequences include dropping a web shell, theft of database and environment credentials, lateral movement within the infrastructure, and in the worst case ransomware or defacement.
But even without a known gadget chain leading to a concrete “run a command” primitive, PHP object injection is not a purely theoretical risk: uncontrolled instantiation of arbitrary classes alone can trigger unexpected side effects via __destruct or __wakeup methods — deleting or overwriting files, corrupting internal state, denial of service through resource exhaustion, or, depending on the classes available in the autoloader, server-side request forgery. Because the vulnerability is triggered via a cookie, it is also easy to automate and exploit at scale against many instances at once.
Mitigation / immediate steps
Operational decision block
- Act now if … ceselector is in production, publicly reachable, and at least one content element is configured with “Persistent Mode: Static”.
- Check with priority if … ceselector is in use but the Persistent Mode configuration of individual content elements is undocumented or unclear.
- Next regular window if … ceselector is not installed, or is verifiably configured only with a persistence mode other than “Static”.
Step 1 — update to the patched version
# check the current version
composer show mmc/ceselector
# update, depending on your version line:
composer require mmc/ceselector:"^6.0.1" # or "^5.0.1", "^4.0.2", "^3.0.3"
# flush caches
vendor/bin/typo3 cache:flush
Step 2 — immediate workaround if an update isn't possible right away
# Option A: reconfigure affected content elements in the backend
# (edit content element → Persistent Mode → switch from "Static"
# to another available persistence mode)
# Option B: temporarily disable the extension (after backup/testing)
composer remove mmc/ceselector
# or in classic mode:
vendor/bin/typo3 extension:deactivate ceselector
# Option C: WAF/reverse-proxy rule against the attack vector
# Block cookies named "T3_ceselector_*" whose value starts with
# "O:" or, URL-encoded, "O%3A" (the PHP serialization prefix
# for objects):
# Example nginx (simplified illustration — implement as a
# map/if combination or at the WAF layer in a real setup):
# if ($http_cookie ~* "T3_ceselector_[^;]*=O%3A") { return 403; }
The WAF rule is a stopgap, not a substitute for the patch — attackers can further obfuscate the payload or rename the cookie if the extension allows it.
Detection / verification
Check version and configuration
# determine the installed version
composer show mmc/ceselector
# locate content elements configured with Persistent Mode: Static
# (backend: page → edit content element → Persistent Mode,
# or check directly in the database/extension configuration,
# depending on how ceselector stores the mode)
Search logs for the attack vector
# search access/application logs for the cookie name and check
# for PHP serialization prefixes ("O:" or URL-encoded "O%3A")
grep -r "T3_ceselector_" /var/log/nginx/access.log* 2>/dev/null | grep -E "O%3A|O:"
grep -r "T3_ceselector_" /var/log/apache2/access.log* 2>/dev/null | grep -E "O%3A|O:"
Check for signs of successful exploitation
# find recently changed/newly created files in the web root
find fileadmin/ typo3temp/ public/ -type f -mtime -30 -newer composer.lock 2>/dev/null
# look for suspicious PHP files outside known extension paths
find fileadmin/ typo3temp/ -iname "*.php" -o -iname "*.phtml" 2>/dev/null
Actively test your own instance
# Only against your own/authorized systems! The public nuclei
# template for CVE-2026-46725 uses exactly the described Monolog
# gadget-chain payload in the "T3_ceselector_" cookie:
nuclei -t http/cves/2026/CVE-2026-46725.yaml -u your-domain.tldOperator guidance
Mid-market
Check ceselector usage and Persistent Mode configuration within a day. If “Static” is in use on a publicly reachable instance: patch immediately or switch to another persistence mode — no delay, given CVSS Critical and an already-circulating public detection/exploit template.
Enterprise / multi-site
Centrally scan all instances' composer.lock for mmc/ceselector, inventory the Persistent Mode configuration per content element. Where “Static” is not business-critical, switch to a different persistence mode proactively, independent of the patch rollout schedule. Add a WAF rule against the cookie pattern as an additional layer of defense.
TYPO3 agencies with client projects
Scan your client base's composer locks for mmc/ceselector, patch affected instances with priority, and include the fix in the next bundled maintenance notice. Since this is a third-party extension, it's also worth asking the vendor whether configurations beyond the four minor releases named here are affected.
Decision block
Act today if: publicly reachable instance + ceselector + Persistent Mode: Static. This week if: ceselector in use, configuration still needs checking. Regular window if: ceselector not installed, or verifiably not configured in Static mode.
Frequently asked questions about CVE-2026-46725
What exactly is PHP object injection?+
When an application passes untrusted data to PHP's unserialize(), an attacker can instantiate any class available in the autoloader. Their constructors and magic methods (__wakeup, __destruct, __toString) run automatically during deserialization — with a suitable “gadget chain” of several such classes, this can be escalated all the way to code execution.
Do I need a public gadget chain for this to be dangerous?+
No — pure PHP object injection is already rated critical, since unexpected magic-method calls can trigger side effects such as file manipulation or denial of service. On top of that, a publicly documented, working chain through Monolog classes already exists here, and Monolog is available via Composer on virtually every TYPO3 installation — which makes unauthenticated RCE here anything but theoretical.
What does “Persistent Mode: Static” actually mean?+
It's a configuration option of the affected content element that controls how ceselector stores selection/state information across requests. In Static mode this happens via a cookie that the extension reads and deserializes on every request — that's exactly the vulnerable code path. Other persistence modes are not affected by this specific flaw.
Is TYPO3 core itself affected?+
Is there a public exploit?+
There is a public nuclei detection template (CVE-2026-46725.yaml) with a complete example payload using the Monolog gadget chain, which on successful exploitation checks the response for the output of an id command. That effectively serves as a public proof of concept, even though it's formally declared a detection template.
How fast do I need to patch?+
For publicly reachable instances running ceselector in Persistent Mode: Static: immediately. CVSS Critical, no authentication required, and a public detection/exploit template already circulates — that's not a combination where you wait for a regular maintenance window.
Conclusion
CVE-2026-46725 is a textbook example of why passing untrusted data into unserialize() is considered fundamentally dangerous in PHP applications — regardless of whether a concrete gadget chain is already known at the time of analysis. Here, one is: a publicly documented chain through widely used Monolog classes turns an “only” critical deserialization flaw into unauthenticated remote code execution on most affected instances. Because the flaw is scoped to a specific configuration (“Persistent Mode: Static”) of a single third-party extension, it can be scoped out quickly — anyone not running ceselector, or not running it in this configuration, is not affected. Anyone who is should not wait for the next regular maintenance window, given the detection template already circulating publicly.
Sources
- TYPO3 News — TYPO3-EXT-SA-2026-013: Remote Code Execution in extension "Content Element Selector" (ceselector) (19 May 2026)
- ProjectDiscovery — nuclei-templates: CVE-2026-46725.yaml (detection template with Monolog gadget-chain payload)
- CVE Playground — CVE-2026-46725: TYPO3 ceselector Insecure Deserialization RCE
- Tenable — CVE-2026-46725
I patch your TYPO3 extensions, audit third-party code for insecure deserialization, and harden cookie-based state storage.
Composer update to the patched ceselector version, an audit of every content element's Persistent Mode configuration, WAF rules against PHP serialization payloads in cookies.
Platform operations, not paper consulting: I continuously review, patch and harden your TYPO3 infrastructure.
About the author
![[Translate to English:] Foto von Kai Ole Hartwig.](/fileadmin/_processed_/e/9/csm_ole-neu_73323ad80d.jpeg)
Kai Ole Hartwig
Programming since 2002 – self-taught, set up my own business with KO-Web in 2012. Over 100 projects, with a focus on security, performance, automation and quality. Today freelance: DevSecOps consulting, training and software development.