From: Khashayar Fereidani <info () fereidani com>
Date: Fri, 19 Jun 2026 09:52:32 +0330
# PHP 8.5.7 `FILTER_SANITIZE_ENCODED` uninitialized read
**Author:** Khashayar Fereidani
**Disclosure Date:** 2026-06-18
**Advisory:** https://fereidani.com/php-857-filtersanitizeencoded-uninitialized-read
**Contact:** https://fereidani.com/contact
## Description
In `ext/filter/sanitizing_filters.c`, the `php_filter_encode_url`
function leaves the `255`th byte (`0xFF`) of a transient array
uninitialized. An array of 256 bytes is populated using `memset(tmp,
1, sizeof(tmp) - 1)`, resulting in `tmp[255]` remaining uninitialized.
When `FILTER_SANITIZE_ENCODED` is applied, this array acts as a lookup
table to determine whether an input byte should be percent-encoded.
Consequently, whether the byte `0xFF` is encoded or left as-is depends
on whatever value happened to be on the stack.
## Proof of concept
```php
<?php
/*
* FILTER_SANITIZE_ENCODED uninitialized read
(ext/filter/sanitizing_filters.c:73).
*
* php_filter_encode_url() does:
* unsigned char tmp[256];
* memset(tmp, 1, sizeof(tmp) - 1); // sets tmp[0..254] = 1,
leaves tmp[255] UNINIT
* ...
* if (tmp[*s]) { percent-encode } else { keep }
*
* So byte 0xFF (index 255) is read UNINITIALIZED: whether it is percent-encoded
* depends on whatever was on the stack. Every other byte is encoded
* deterministically. Effect: inconsistent URL-encoding of 0xFF (low severity;
* no crash / no memory corruption, just UB + nondeterministic sanitizing).
*
* Run: php poc.php
* expect: 0xFF kept RAW (ff...) while 0xFE is correctly percent-encoded (%FE)
*/
$out = filter_var("\xff\xfeabc", FILTER_SANITIZE_ENCODED);
echo "in : ", bin2hex("\xff\xfeabc"), "\n";
echo "out: ", bin2hex($out), "\n";
echo "0xFF was kept raw and 0xFE was percent-encoded => tmp[255] read
uninitialized.\n";
```
Running the script results in:
```bash
in : fffe616263
out: ff254645616263
0xFF was kept raw and 0xFE was percent-encoded => tmp[255] read uninitialized.
```
## Impact
The impact is low. No crashes or memory corruption can occur as a
result of this bug. The sole impact is nondeterministic sanitizing of
the `0xFF` byte, which leads to inconsistent URL-encoding based on
uninitialized stack data unless it smartly gets used among other
vulnerabilities in a chain.
## Solution
Replace `sizeof(tmp) - 1` with `sizeof(tmp)` in the `memset` call in
`ext/filter/sanitizing_filters.c` to fully initialize the lookup
table.
_______________________________________________
Sent through the Full Disclosure mailing list
https://nmap.org/mailman/listinfo/fulldisclosure
Web Archives & RSS: https://seclists.org/fulldisclosure/
Current thread:
- PHP 8.5.7 `FILTER_SANITIZE_ENCODED` uninitialized read Khashayar Fereidani (Jun 20)