In un certo senso questa domanda può essere visto come un'estensione del this one.sicurezza di questi metodi per codificare e decodificare le sessioni PHP
Stiamo considerando di rilasciare una classe che gestisce la deserializzazione e la serializzazione dei dati di sessione memorizzati in una tabella su un sito Web di produzione su larga scala in modo che possiamo modificare dati di sessione arbitrari.
Il problema è che, session_decode()
popola la corrente $_SESSION
senza restituire una matrice decodificato, e session_encode()
non codifica un dato array (restituisce solo una stringa serializzata della sessione corrente.)
Il gestore sessione di serializzazione di default PHP non utilizzare semplicemente serialize()
per codificare le sessioni e quindi l'unico modo per ottenere le stesse funzionalità di codifica e decodifica una sessione è di uno spostamento della variabile globale $_SESSION
muoversi (cioè deposito nella sessione, recuperare i dati e ripristinare) o provando per riprodurre un'implementazione di ciò che fa lo session.serialize_handler
.
Abbiamo optato per il metodo di riproduzione quest'ultimo come sembra meno invadente. Ci sono stati un certo numero di tentativi di questa riproduzione nella sezione commenti di session_encode e session_decode nei documenti. Ne ho scelti due che ritengo siano i più affidabili e li ho applicati. Il metodo di decodifica sembra abbastanza robusto ma il metodo di codifica, sebbene funzioni, è stato pubblicato più di 5 anni fa
Siamo ancora riluttanti a implementarlo semplicemente perché potrebbero esserci casi di margini invisibili che causeranno la rottura di questi metodi.
In definitiva, sto cercando:
- esempi che si rompono i metodi di seguito, o
- rassicurazione che questi metodi sono stati utilizzati nella produzione e non si romperà
- forse alternative che sono stati provati e testati in produzione?
Grazie a tutti in anticipo!
Il codice:
class Session extends BaseSession
{
/**
* Taken from http://www.php.net/manual/en/function.session-decode.php#108037
*/
public function unserialized() {
$session_data = $this->content;
$method = ini_get("session.serialize_handler");
switch ($method) {
case "php":
return self::unserialize_php($session_data);
break;
case "php_binary":
return self::unserialize_phpbinary($session_data);
break;
default:
throw new Exception("Unsupported session.serialize_handler: " . $method . ". Supported: php, php_binary");
}
}
/**
* Taken from http://www.php.net/manual/en/function.session-encode.php#76425
*/
public function serialize($array, $safe = true) {
// the session is passed as refernece, even if you dont want it to
if($safe) $array = unserialize(serialize($array)) ;
$raw = '' ;
$line = 0 ;
$keys = array_keys($array) ;
foreach($keys as $key) {
$value = $array[ $key ] ;
$line ++ ;
$raw .= $key .'|' ;
if(is_array($value) && isset($value['huge_recursion_blocker_we_hope'])) {
$raw .= 'R:'. $value['huge_recursion_blocker_we_hope'] . ';' ;
} else {
$raw .= serialize($value) ;
}
$array[$key] = Array('huge_recursion_blocker_we_hope' => $line) ;
}
$this->content = $raw;
$this->save();
}
private static function unserialize_php($session_data) {
$return_data = array();
$offset = 0;
while ($offset < strlen($session_data)) {
if (!strstr(substr($session_data, $offset), "|")) {
throw new Exception("invalid data, remaining: " . substr($session_data, $offset));
}
$pos = strpos($session_data, "|", $offset);
$num = $pos - $offset;
$varname = substr($session_data, $offset, $num);
$offset += $num + 1;
$data = unserialize(substr($session_data, $offset));
$return_data[$varname] = $data;
$offset += strlen(serialize($data));
}
return $return_data;
}
private static function unserialize_phpbinary($session_data) {
$return_data = array();
$offset = 0;
while ($offset < strlen($session_data)) {
$num = ord($session_data[$offset]);
$offset += 1;
$varname = substr($session_data, $offset, $num);
$offset += $num;
$data = unserialize(substr($session_data, $offset));
$return_data[$varname] = $data;
$offset += strlen(serialize($data));
}
return $return_data;
}
}
domanda Ben scritto :) –
Thanks :) btw su [questa domanda] (http://stackoverflow.com/questions/9948182/custom-serialize- handler-for-custom-php-sessionhandler-db-storage? rq = 1) qualcuno ha menzionato l'utilizzo di un gestore di serializzazione personalizzato, tuttavia sarebbe una mossa troppo grande per noi, quindi siamo bloccati sul gestore predefinito ~ –