PR-5.4-dev Pending

User tests: Successful: Unsuccessful:

avatar pwner-jw
pwner-jw
8 Jul 2026

extract.php read ZIP entry filenames directly from the archive's local file headers and used them unvalidated in mkdir() and fopen() calls during extraction. A crafted entry name containing ".." segments or an absolute path (e.g. "../../../../etc/cron.d/x" or "/var/www/other-site/shell.php") could therefore write files outside the intended destination directory, commonly known as a Zip Slip vulnerability.

This adds isPathTraversalAttempt(), which rejects entry names that are absolute (Unix root, Windows drive letter, or UNC path) or contain a ".." path segment. The check runs on the raw entry name before addPath is prepended, and reuses the existing $isBannedFile / skip-and-seek mechanism already used for "." and ".." basenames and the skipFiles list, so rejected entries are safely skipped without disrupting the ZIP read pointer.

No behavior change for well-formed archives.

Pull Request resolves # .

  • I read the Generative AI policy and my contribution is either not created with the help of AI or is compatible with the policy and GNU/GPL 2 or later.

Summary of Changes

Added a new private method isPathTraversalAttempt() to ZIPExtraction in administrator/components/com_joomlaupdate/extract.php, and one additional check in readFileHeader() that marks entries as banned (using the existing $isBannedFile skip logic) when the raw entry filename is an absolute path or contains a .. path segment.

Testing Instructions

  1. Apply this patch to a Joomla installation.
  2. Craft a test ZIP archive containing an entry with a path-traversal name, e.g. ../../../evil.php, an absolute path /tmp/evil.php, or a Windows-style C:\evil.php.
  3. Also include a normal, well-formed entry, e.g. administrator/components/com_example/example.php, in the same archive.
  4. Trigger extract.php against this archive (e.g. via the update flow, or by calling it directly with the required password/task parameters).
  5. Confirm the malicious entries are skipped (no file is written outside the destination directory) and the well-formed entry extracts normally to the expected path.

Actual result BEFORE applying this Pull Request

A ZIP entry with a ..-containing or absolute path name is extracted using its literal, unvalidated path, allowing mkdir()/fopen() calls to create directories and write files outside the intended extraction root.

Expected result AFTER applying this Pull Request

Entries with .. segments or absolute paths are detected before extraction and skipped, consistent with how other banned entries (e.g. ./.. basenames, skipFiles list) are already handled. Well-formed archives extract unchanged.

Link to documentations

Please select:

  • Documentation link for guide.joomla.org:
  • No documentation changes for guide.joomla.org needed
  • Pull Request link for manual.joomla.org:
  • No documentation changes for manual.joomla.org needed
avatar pwner-jw pwner-jw - open - 8 Jul 2026
avatar pwner-jw pwner-jw - change - 8 Jul 2026
Status New Pending
avatar joomla-cms-bot joomla-cms-bot - change - 8 Jul 2026
Category Administration com_joomlaupdate
avatar pwner-jw
pwner-jw - comment - 8 Jul 2026

Hi @brianteeman, thanks for flagging — this was already reported through the
official channel and reviewed by the Security Strike Team. Harald assessed it as not meeting the security-issue bar, since exploitation requires Super User access, which already implies full code execution via the standard extension/update upload flow. He suggested I open this as a normal hardening PR on the public tracker, which is what this is.

avatar brianteeman
brianteeman - comment - 8 Jul 2026

Strange, because yes it is correct that you would need to be a Super User and a super user can knowingly do all sorts of things in this case you are describing the potential of a super user being tricked into unkowingly uploading a zipslipped joomla update

avatar richard67 richard67 - change - 8 Jul 2026
Title
[com_joomlaupdate] Fix path traversal (Zip Slip) in extract.php
[5.4] [com_joomlaupdate] Fix path traversal (Zip Slip) in extract.php
avatar richard67 richard67 - edited - 8 Jul 2026
avatar pwner-jw
pwner-jw - comment - 8 Jul 2026

@brianteeman Thanks for reviewing this.

If this gets merged, I'd appreciate it if the Security Strike Team could revisit whether it qualifies for a CVE. If not, I'd be grateful for an acknowledgment of the security hardening contribution.

avatar pwner-jw pwner-jw - change - 12 Jul 2026
Labels Added: PR-5.4-dev
avatar pwner-jw
pwner-jw - comment - 14 Jul 2026

@brianteeman @richard67 any update?

avatar alikon
alikon - comment - 14 Jul 2026

@pwner-jw
for speed-up the tests can you provide "a test ZIP archive containing an entry with a path-traversal name...."

avatar pwner-jw
pwner-jw - comment - 17 Jul 2026

@alikon were u able to test?

avatar brianteeman
brianteeman - comment - 17 Jul 2026

I can confirm that before applying the pr then performing an update with the supplied zipslip wrote a php file to the root of the web space
I can confirm that after applying pr then the php file was not written

As I stated before you would need to be a super user but I can see a scenario where a super user was tricked into downloading and then uploading a malicious joomla update zip

Not marking it as a success or failure as Idont know enough about this to know if the PR is sufficient

avatar pwner-jw
pwner-jw - comment - 18 Jul 2026

@brianteeman Agreed, and that's the distinction worth flagging back to the JSST. "Requires Super User" conflates the privilege needed to trigger extraction with the intent needed to cause the traversal. A Super User running the normal update flow isn't consenting to writes outside administrator/ they're consenting to a scoped install. If the ZIP source is attacker-influenced (compromised update stream, malicious package, social-engineered install), their legitimate action becomes the delivery mechanism for an out-of-scope write, e.g. a web shell in a sibling site or a cron job. That's privilege escalation from "site admin" to "host compromise," not a no-op.
Either way, functionally this is the same bug class as every other Zip Slip CVE assigned in extraction libraries, none of those needed a malicious caller, only a malicious archive.

avatar pwner-jw
pwner-jw - comment - 18 Jul 2026

thanks, done

avatar kdalal-vulncheck
kdalal-vulncheck - comment - 20 Jul 2026

Hello @richard67 Richard,
This issue is fixed in 9678a17 can you please merge this pull request?

avatar richard67
richard67 - comment - 20 Jul 2026

Hello @richard67 Richard, This issue is fixed in 9678a17 can you please merge this pull request?

@kdalal-vulncheck Each pull request needs 2 successful human test before it can be considered to be merged.

Add a Comment

Login with GitHub to post a comment