Pending

User tests: Successful: Unsuccessful:

avatar ManoharPaturi
ManoharPaturi
4 Oct 2026

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

The local filesystem adapter of com_media validates every path it acts on through getLocalPath(), which contains the Path::check() call that keeps the request inside the adapter root. getResource() is the one exception: it concatenates the raw path onto the root and opens it directly:

return fopen($this->rootPath . '/' . $path, 'r');

Today both call sites in ApiModel only pass paths that were already normalised by getFile() or getFiles(), so nothing is reachable through this gap at the moment. The asymmetry is a footgun for future callers: any code path that starts invoking getResource() with a request supplied path would silently skip the containment check that all other read and write operations enforce.

This PR routes getResource() through getLocalPath() as well, so a traversal style path now fails with an InvalidPathException before anything is opened. A missing file now also raises a FileNotFoundException, consistent with getFile(), instead of returning false from fopen() together with a PHP warning.

Unit tests cover the readable resource case, the traversal rejection and the missing file case.

Testing Instructions

Run the adapter unit tests:

libraries/vendor/bin/phpunit tests/Unit/Plugin/Filesystem/Local/Adapter/LocalAdapterTest.php

Optionally, with the API enabled, request GET /api/index.php/v1/media/files/local/{path}?content=true for an existing file and confirm the base64 content is still returned as before.

Actual result BEFORE applying this Pull Request

getResource() opens the raw concatenation of the adapter root and the given path. No validation runs inside the method itself, and a missing file yields a PHP warning plus a false return value.

Expected result AFTER applying this Pull Request

getResource() resolves the path through getLocalPath() and throws an InvalidPathException for any path escaping the adapter root, and a FileNotFoundException for missing files. Valid files are returned exactly as before.

Link to documentations

  • No documentation changes for guide.joomla.org needed
  • No documentation changes for manual.joomla.org needed
avatar ManoharPaturi ManoharPaturi - open - 4 Oct 2026
avatar ManoharPaturi ManoharPaturi - change - 4 Oct 2026
Status New ⇒ Pending
avatar joomla-cms-bot joomla-cms-bot - change - 4 Oct 2026
Category ⇒ Front End Plugins Unit Tests

Add a Comment

Login with GitHub to post a comment