User tests: Successful: Unsuccessful:
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 # .
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.
../../../evil.php, an absolute path /tmp/evil.php, or a Windows-style C:\evil.php.administrator/components/com_example/example.php, in the same archive.extract.php against this archive (e.g. via the update flow, or by calling it directly with the required password/task parameters).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.
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.
Please select:
| Status | New | ⇒ | Pending |
| Category | ⇒ | Administration com_joomlaupdate |
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.
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
| Title |
|
||||||
@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.
| Labels |
Added:
PR-5.4-dev
|
||
@brianteeman @richard67 any update?
https://drive.google.com/drive/folders/1DzfyuLlqyLQ2_3fzIcRXIz0vOcUYUPon
ig this should help
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
@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.
thanks, done
Hello @richard67 Richard,
This issue is fixed in 9678a17 can you please merge this pull request?
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.
Hello @richard67 , could you please share an update on when the manual checks are expected to be completed? This issue is critical, so a timeline would be really helpful.
Hello @richard67 , could you please share an update on when the manual checks are expected to be completed? This issue is critical, so a timeline would be really helpful.
@pwner-jw Joomla is a project of a community of volunteers. So we all do it in our spare time. Everybody who can contribute here e.g. by opening issues or creating pull requests can also test other people's pull request. I have no influence on that.
This issue is critical
Where is it critical? As updating the core is restricted to superusers only, where is it critical in practice?
Besides that: Keeping maintainers or release managers busy with pinging them just because of impatience does not really help the project.
Thanks for the feedback, Richard. You're right, I realise I've followed up a few times, and I can see how that creates unnecessary noise. That wasn't my intention, and I appreciate that everyone working on Joomla is volunteering their time.
I'll hold off on further follow-ups and wait for the review process. Thanks again to everyone involved in maintaining the project.
You're right, I realise I've followed up a few times, and I can see how that creates unnecessary noise. That wasn't my intention, and I appreciate that everyone working on Joomla is volunteering their time.
I'll hold off on further follow-ups and wait for the review process. Thanks again to everyone involved in maintaining the project.
Hello @richard67 Richard,
Has this issue gone through 2 successful human test? If so, can you please merge this pull request. This issue is fixed in 9678a17.
Hello @richard67 Richard, Has this issue gone through 2 successful human test? If so, can you please merge this pull request. This issue is fixed in 9678a17.
@kdalal-vulncheck WHy do you put pressure on me? We will merge it when we have time. Besides that you will see on GitHub in the CI checks at the bottom if the PR has successful tests or not. Currently it still needs 2 tests. When it has them, the RTC label will be set by a maintainer or release manager.
Please stop to keep maintainers and release managers like me unnecessarily busy by pinging them for no reason. The issue which this PR fixes is nothing urgent.
@kdalal-vulncheck please go check the discloure@ mailbox of your company.
Your company has yet again violated the CVE CNA coverage of Joomla for all Joomla related issues and assigned a CVE ID to an behavior that has clearly been assessed as "not as security issue" by the vendor. The violation of our CNA scope has now happend multiple times and I'm really starting to question your internal processes.
@kdalal-vulncheck please go check the disclosure@ mailbox of your company.
Your company has yet again violated the CVE CNA coverage of Joomla for all Joomla related issues and assigned a CVE ID to an behavior that has clearly been assessed as "not as security issue" by the vendor. The violation of our CNA scope has now happend multiple times and I'm really starting to question your internal processes.
Hello @SniperSister David,
Apologies — CVE-2026-73327 was assigned in error. We don't assign for products in another CNA's scope, and Joomla core is clearly yours. That was by mistake.
We're rejecting the record now with scope as the stated reason.
@muhme and @QuyTon Sorry for the late reply.
I’ve kept this as a separate if intentionally. The existing checks and isPathTraversalAttempt() represent independent reasons for marking an archive entry as banned: the former handles the legacy ./.. filename check, while the new check covers absolute paths (Unix, Windows drive/UNC) and .. path segments anywhere in the raw ZIP entry name. The $skipFiles check below is also an independent configured exclusion.
All three checks only contribute to the $isBannedFile flag; the entry is skipped once that flag is true. Using elseif here would only short-circuit evaluation of the subsequent validation rules and doesn't provide any additional security benefit. I therefore prefer keeping the checks independent while preserving the existing banned-file handling semantics.
| Labels |
Added:
Updates Requested
|
||
| Labels |
Removed:
Updates Requested
|
||
https://github.com/joomla/joomla-cms/security