PHP
Сериализация
Поиск…
Синтаксис
- string serialize (смешанное значение $)
параметры
параметр | подробности |
---|---|
значение | Значение для сериализации. serialize () обрабатывает все типы, за исключением типа ресурса . Вы можете даже сериализовать () массивы, содержащие ссылки на себя. Также будут сохранены циклические ссылки внутри массива / объекта, который вы сериализуете. Любая другая ссылка будет потеряна. При сериализации объектов PHP будет пытаться вызвать функцию-член __sleep () перед сериализацией. Это позволяет объекту выполнять очистку в последнюю минуту и т. Д. До сериализации. Аналогично, когда объект восстанавливается с использованием unserialize (), вызывается функция члена __wakeup () . У частных членов объекта есть имя класса, добавленное к имени участника; защищенные члены имеют «*», добавленные к имени участника. Эти предварительные значения имеют нулевые байты с обеих сторон. |
замечания
Сериализация использует следующие строковые структуры:
[..]
являются заполнителями.
Тип | Состав |
---|---|
строка | s:[size of string]:[value] |
целое число | i:[value] |
двойной | d:[value] |
логический | b:[value (true = 1 and false = 0)] |
Ноль | N |
объект | O:[object name size]:[object name]:[object size]:{[property name string definition]:[property value definition];(repeated for each property)} |
массив | a:[size of array]:{[key definition];[value definition];(repeated for each key value pair)} |
Сериализация различных типов
Создает сохраняемое представление значения.
Это полезно для хранения или передачи значений PHP без потери их типа и структуры.
Чтобы снова преобразовать сериализованную строку в значение PHP, используйте unserialize () .
Сериализация строки
$string = "Hello world";
echo serialize($string);
// Output:
// s:11:"Hello world";
Сериализация двойного
$double = 1.5;
echo serialize($double);
// Output:
// d:1.5;
Сериализация поплавка
Поплавок сериализуется как удваивается.
Сериализация целого числа
$integer = 65;
echo serialize($integer);
// Output:
// i:65;
Сериализация логического
$boolean = true;
echo serialize($boolean);
// Output:
// b:1;
$boolean = false;
echo serialize($boolean);
// Output:
// b:0;
Сериализация нуля
$null = null;
echo serialize($null);
// Output:
// N;
Сериализация массива
$array = array(
25,
'String',
'Array'=> ['Multi Dimension','Array'],
'boolean'=> true,
'Object'=>$obj, // $obj from above Example
null,
3.445
);
// This will throw Fatal Error
// $array['function'] = function() { return "function"; };
echo serialize($array);
// Output:
// a:7:{i:0;i:25;i:1;s:6:"String";s:5:"Array";a:2:{i:0;s:15:"Multi Dimension";i:1;s:5:"Array";}s:7:"boolean";b:1;s:6:"Object";O:3:"abc":1:{s:1:"i";i:1;}i:2;N;i:3;d:3.4449999999999998;}
Сериализация объекта
Вы также можете сериализовать объекты.
При сериализации объектов PHP будет пытаться вызвать функцию-член __sleep () перед сериализацией. Это позволяет объекту выполнять очистку в последнюю минуту и т. Д. До сериализации. Аналогично, когда объект восстанавливается с использованием unserialize (), вызывается функция члена __wakeup () .
class abc {
var $i = 1;
function foo() {
return 'hello world';
}
}
$object = new abc();
echo serialize($object);
// Output:
// O:3:"abc":1:{s:1:"i";i:1;}
Обратите внимание, что Closures нельзя сериализовать:
$function = function () { echo 'Hello World!'; };
$function(); // prints "hello!"
$serializedResult = serialize($function); // Fatal error: Uncaught exception 'Exception' with message 'Serialization of 'Closure' is not allowed'
Проблемы безопасности с unserialize
Использование функции unserialize
для нессериализации данных с пользовательского ввода может быть опасным.
Предупреждение от php.net
Предупреждение Не пропускайте недоверенный ввод пользователя в unserialize (). Несериализация может привести к тому, что код загружается и выполняется из-за экземпляра объекта и автозагрузки, и злоумышленник может воспользоваться этим. Используйте безопасный стандартный формат обмена данными, такой как JSON (через json_decode () и json_encode ()), если вам необходимо передать сериализованные данные пользователю.
Возможные атаки
- Инъекция объектов PHP
Инъекция объектов PHP
Инъекция объектов PHP - это уязвимость уровня приложения, которая может позволить злоумышленнику выполнять различные виды вредоносных атак, таких как инъекция кода, инъекция SQL, обход траектории и отказ в обслуживании приложений в зависимости от контекста. Уязвимость возникает, когда пользовательский ввод не подвергается надлежащей дезинфекции перед передачей функции unserialize () PHP. Поскольку PHP разрешает сериализацию объектов, злоумышленники могут передавать ad-hoc сериализованные строки уязвимому вызову unserialize (), что приводит к произвольной инъекции PHP-объектов в область приложения.
Чтобы успешно использовать уязвимость PHP Object Injection, необходимо выполнить два условия:
- Приложение должно иметь класс, который реализует магический метод PHP (например,
__wakeup
или__destruct
), который может использоваться для выполнения вредоносных атак или для запуска «цепочки POP». - Все классы, используемые во время атаки, должны быть объявлены при
unserialize()
уязвимостиunserialize()
, в противном случае для таких классов должна поддерживаться функция автозагрузки объектов.
Пример 1 - Атака на траекторию
В приведенном ниже примере показан класс PHP с использованием метода __destruct
:
class Example1
{
public $cache_file;
function __construct()
{
// some PHP code...
}
function __destruct()
{
$file = "/var/www/cache/tmp/{$this->cache_file}";
if (file_exists($file)) @unlink($file);
}
}
// some PHP code...
$user_data = unserialize($_GET['data']);
// some PHP code...
В этом примере злоумышленник может удалять произвольный файл с помощью атаки Traverse, например, запрашивая следующий URL-адрес:
http://testsite.com/vuln.php?data=O:8:"Example1":1:{s:10:"cache_file";s:15:"../../index.php";}
Пример 2 - Инъекционная атака кода
В приведенном ниже примере показан класс PHP с использованием метода __wakeup:
class Example2
{
private $hook;
function __construct()
{
// some PHP code...
}
function __wakeup()
{
if (isset($this->hook)) eval($this->hook);
}
}
// some PHP code...
$user_data = unserialize($_COOKIE['data']);
// some PHP code...
В этом примере злоумышленник может выполнить атаку по вводу кода, отправив HTTP-запрос следующим образом:
GET /vuln.php HTTP/1.0
Host: testsite.com
Cookie: data=O%3A8%3A%22Example2%22%3A1%3A%7Bs%3A14%3A%22%00Example2%00hook%22%3Bs%3A10%3A%22phpinfo%28%29%3B%22%3B%7D
Connection: close
Если параметр cookie файла cookie был сгенерирован следующим скриптом:
class Example2
{
private $hook = "phpinfo();";
}
print urlencode(serialize(new Example2));