@galliard

Почему в PHP zlib не работает во врапперах?

Есть значит некая текстовая строка, которая заархивирована zip'ом и после еще закодирована алгоритмом Base64. Мне нужно раскодировать ее обратно, с этим прекрасно справляются функции:

$sourceFile = 'source.txt';

$source = file_get_contents($sourceFile);

var_dump(gzuncompress($base64_decode($source)));


Так же можно сделать это через фильтры стримов:
$fp = fopen($sourceFile, 'rb');

stream_filter_append($fp, 'convert.base64-decode');
stream_filter_append($fp, 'zlib.inflate', STREAM_FILTER_READ, ['level' => 2, 'window' => 15, 'memory' => 6]);

var_dump(stream_get_contents($fp));

fclose($fp);


Это более многословно, но тоже прекрасно работает. Но если можно через стримы, то можно и через врапперы, например так:
var_dump(file_get_contents("php://filter/read=convert.base64-decode|zlib.inflate/resource=$sourceFile"));


И вот тут облом. Нет, base64-decode работает прекрасно, а вот zlib.inflate - не работает. Всмысле возвращает пустую строку.

Еще в интернетах находил вот такой вариант:
var_dump(file_get_contents("compress.zlib://data://text/plain;base64,$source"));

Но это так же не работает, возвращает base64-декодированную строку, а вот распаковка архива не происходит.

Пробовал и на windows, и на linux машинах, а так же на версиях php от 5.6 до 7.4, результат везде одинаков.

Почему zlib не работает именно во врапперах?

При этом не понятно даже как это отлаживать, потому что никаких ошибок не возникает, просто возвращается пустая строка.
  • Вопрос задан
  • 80 просмотров
Пригласить эксперта
Ответы на вопрос 1
@alexalexes
Попробуйте одинарные кавычки вместо двойных.
'php://filter/read=convert.base64-decode|zlib.inflate/resource='.$sourceFile

PS:
Нашел вот такой комментарий на Хакере.
https://xakep.ru/2012/11/22/php-filter-wrapper-attacks/
При всех выгодах данный метод уничтожения стопперов не может быть универсальным. В 2009 году было замечено, что функция base64_decode некорректно обрабатывает строки, содержащие в середине знаки равенства [#47174]. Этот баг был довольно оперативно исправлен для функции base64_decode, но для фильтра convert.base64-decode никаких исправлений сделано не было. Поэтому, если при «выдавливании» на каком-то шаге получаются данные, содержащие знак равенства, дальнейшее применение фильтра convert.base64-decode уничтожит преобразуемую строку.

$s = 'php://filter/read=convert.base64-decode/resource=data:,dGVzdA==CRAP'; 
var_dump(file_get_contents($s)); // print: string(0) ""

Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы