Security Advisory ยท Published 2026-05-27

Magento 2 CVE-2026-45247: Unauthenticated RCE Through a Cookie. Here's What to Do.

CVE-2026-45247 is a PHP object injection in the Mirasvit Full Page Cache Warmer extension for Magento 2. The vulnerable code path doesn't require a login - it reads a serialized PHP object from the CacheWarmer cookie on every request. That can turn a visitor-controlled cookie into code execution on the server. CVSS 9.8. If your store runs this extension, check it before leaving it public.

What's actually happening

Mirasvit's Full Page Cache Warmer is a popular Magento 2 extension that pre-warms the cache for product pages, category pages, and CMS content. To track which pages a visitor has already warmed, it serializes state into a cookie called CacheWarmer and calls PHP's native unserialize() on it when the next request arrives.

That unserialize() call is the problem. PHP's deserializer will instantiate classes found in serialized data - including classes with __destruct(), __wakeup(), or __toString() magic methods that do dangerous things. Magento's codebase and its dependencies include enough moving parts that cookie deserialization should be treated as an emergency patch, not a theoretical warning.

What makes this particularly bad: the extension is installed across thousands of Magento 2 stores because page performance directly affects conversion rate. It's not an obscure plugin - it's the kind of thing an agency installs by default on every store build.

Is your store affected?

Step 1: Check if Mirasvit Cache Warmer is installed

# From your Magento root directory
php bin/magento module:status | grep -i mirasvit

# Or check composer
composer show mirasvit/module-cache-warmer 2>/dev/null | grep "versions\|name"

# Or check the filesystem
ls vendor/mirasvit/module-cache-warmer/ 2>/dev/null && echo "INSTALLED" || echo "not found"

If the module isn't there, this CVE doesn't apply to you. Close this tab and go work on something else.

Step 2: Check the version

cat vendor/mirasvit/module-cache-warmer/composer.json | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('version','not found'))"

# Alternative
grep '"version"' vendor/mirasvit/module-cache-warmer/composer.json

Versions before 1.11.12 are vulnerable. Version 1.11.12 and above contain the patch. If your version is 1.11.11 or earlier, keep reading.

Step 3: Verify the patch status without relying on version numbers

Version numbers can lie if someone applied a hotfix without incrementing the version. The actual fix replaces the raw unserialize() call with a safer alternative. Check the source directly:

grep -r "unserialize" vendor/mirasvit/module-cache-warmer/Model/ 2>/dev/null
grep -r "unserialize" vendor/mirasvit/module-cache-warmer/Service/ 2>/dev/null

On a patched install, these greps should return nothing, or results that don't involve cookie data. On a vulnerable install, you'll find an unserialize(\$cookieValue) pattern somewhere in the cache warming service or cookie handler class.

Patching

Update via composer (recommended)

composer update mirasvit/module-cache-warmer --with-dependencies
php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento cache:flush

The setup:upgrade step matters - the extension may have schema or configuration changes in 1.11.12. Don't skip it.

If you're on a locked composer.json

Some agency-managed stores have a locked composer.json with specific version pins. If composer update tells you the constraint prevents upgrading, you have two options: change the version constraint in composer.json to ^1.11.12 and re-run, or disable the module entirely while you sort out the update.

# Temporary mitigation if you can't patch immediately
php bin/magento module:disable Mirasvit_CacheWarmer
php bin/magento cache:flush

Disabling the module kills the cache warming functionality but eliminates the attack surface entirely. Your store stays online, just without pre-warming. On a high-traffic store that's a real performance hit, so treat this as a bridge measure, not a long-term answer.

Check whether someone already used this against your store

PHP object injection via a cookie is quiet - there's no SQL error, no 500 response, no obvious anomaly in the access log if the exploit works cleanly. But the initial probe attempts leave traces.

# Look for requests with the CacheWarmer cookie carrying unusual content
grep "CacheWarmer" /var/log/nginx/access.log | grep -v "^$" | awk '{"{"}'print $7, $11{"}"}'  | sort | uniq -c | sort -rn | head -30

# PHP serialized payloads often start with O: or a: or s: in the cookie value
# URL-encoded equivalents are %4F%3A (O:), %61%3A (a:)
grep -i "CacheWarmer.*%4[Ff]%3[Aa]\|CacheWarmer.*O%3A\|CacheWarmer.*O:" /var/log/nginx/access.log | wc -l

Any count above zero means someone was probing the endpoint. It doesn't mean they succeeded, but it means you were a target.

If you suspect active compromise: audit pub/media/ and pub/static/ for PHP files (there should be none), check recently modified files, and look for new admin accounts or API integrations you didn't create.

# Hunt for webshells in directories that shouldn't have PHP
find pub/ -name "*.php" -mtime -30 -ls
find var/cache/ -name "*.php" -ls
find generated/ -name "*.php" -mtime -14 -ls

# Recent PHP file modifications across the store
find . -name "*.php" -newer vendor/mirasvit/module-cache-warmer/composer.json -not -path "./vendor/*" -not -path "./.git/*" | head -50

The broader lesson here

unserialize() on untrusted input has been on PHP's "do not do this" list for over a decade. The PHP documentation literally says "Do not pass untrusted user input to unserialize() regardless of the options value." The Mirasvit team put this in a cookie - the most untrusted input source in a web application.

The fix is to use JSON encoding instead of PHP serialization for cookie state, or to use a HMAC-verified signed cookie that an attacker can't forge. Version 1.11.12 does exactly that. The extension continues to work; it just doesn't hand attackers a code execution primitive on every page load.

If you run other Mirasvit extensions, it's worth auditing them for similar patterns. One vendor with a unserialize() habit tends to have it in more than one place.

FAQ

I have Mirasvit Cache Warmer installed but it's disabled. Am I affected?

If the module is disabled via php bin/magento module:disable, the code doesn't run. You're not exposed. That said, update it anyway so you don't accidentally re-enable a vulnerable version later.

My store is behind Cloudflare / a WAF. Does that help?

Possibly, if your WAF has a rule that blocks PHP serialized payloads in cookie values. Cloudflare's managed ruleset has some PHP object injection detection, but it's not bulletproof - attackers obfuscate. Don't rely on a WAF as your primary mitigation. Patch the extension.

Is there a CVE page I can track for updates?

NVD CVE-2026-45247 is the canonical source. The vendor changelog and security writeups are useful for confirming the fixed version and affected code path.

Running Magento 2 and not sure what extensions you have?

A complete Magento 2 extension audit takes about an hour - check installed modules against known CVE lists, hunt for unserialize() patterns, review admin account log, and generate a patch priority list. If you want that done properly rather than guessed at from a terminal, that's what we're here for.

Request CVE repair

References

Related guides