Skip to content

[5.4] Prevent PHAR stub detection bypass across InputFilter chunk boundaries#47952

Open
saddamr3e wants to merge 1 commit into
joomla:5.4-devfrom
saddamr3e:inputfilter-boundary-scan-bypass
Open

[5.4] Prevent PHAR stub detection bypass across InputFilter chunk boundaries#47952
saddamr3e wants to merge 1 commit into
joomla:5.4-devfrom
saddamr3e:inputfilter-boundary-scan-bypass

Conversation

@saddamr3e

Copy link
Copy Markdown
  • 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

InputFilter::isSafeFile() scans uploaded file contents in 131072-byte (128 KB) chunks. To catch a dangerous signature that lands across the boundary between two reads, it carried over the tail of each read into the next one — but only a fixed 10 bytes. That value was sized for <?php (5 bytes) and never updated when the longer __HALT_COMPILER() phar-stub check (17 bytes, enabled by default via phar_stub_in_content) was added to the same loop.

As a result, a phar stub aligned so that 11 or more of its 17 bytes fall before a 128 KB boundary is split across two reads and never detected, so the file passes the content scan.

This change computes the carry-over ($scanOverlap) from the longest signature actually being scanned given the current options, instead of a magic number. For the default options that is strlen('__HALT_COMPILER()') - 1 = 16. It also stays correct automatically if the forbidden-extension list or signature set changes.

Files:

  • libraries/src/Filter/InputFilter.php — compute $scanOverlap; replace substr($data, -10) with substr($data, -$scanOverlap).
  • tests/Unit/Libraries/Cms/Filter/InputFilterTest.php — new regression tests.

Testing Instructions

Run the bundled unit tests:

libraries/vendor/bin/phpunit tests/Unit/Libraries/Cms/Filter/InputFilterTest.php

Actual result BEFORE applying this Pull Request

isSafeFile() returns true (file considered safe) the phar stub spanning the read boundary is not detected and the new unit tests fail.

Expected result AFTER applying this Pull Request

isSafeFile() returns false (file rejected) the phar stub is detected regardless of where it falls relative to the read boundary Large benign files containing none of the scanned signatures are still accepted (no false positives) All new unit tests pass

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

@saddamr3e
saddamr3e force-pushed the inputfilter-boundary-scan-bypass branch from f849e67 to 4f52f9b Compare June 13, 2026 18:32
@richard67 richard67 added the bug label Jun 28, 2026
@richard67 richard67 changed the title Prevent PHAR stub detection bypass across InputFilter chunk boundaries [5.4] Prevent PHAR stub detection bypass across InputFilter chunk boundaries Jun 28, 2026
@saddamr3e

Copy link
Copy Markdown
Author

any update?

@muhme

muhme commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Hi @saddamr3e, thank you for your contribution. This PR is still awaiting two human tests/code reviews. As with many parts of the project, reviews depend on volunteer availability.

@saddamr3e

Copy link
Copy Markdown
Author

Understood, will wait. For anyone picking this up to test: the bundled unit tests reproduce the boundary case directly (libraries/vendor/bin/phpunit tests/Unit/Libraries/Cms/Filter/InputFilterTest.php). The two phar-stub tests fail without the InputFilter change and pass with it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants