2013-03-21 14 views
7

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; 
    } 
} 
+0

domanda Ben scritto :) –

+0

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 ~ –

risposta

1

Igbinary (https://github.com/igbinary/igbinary/) è un rimpiazzo per il serializzatore php standard. Invece di tempo e spazio che consumano la rappresentazione testuale, igbinary memorizza le strutture di dati php in forma binaria compatta. I risparmi sono significativi quando si utilizzano memorie memcached o simili basate su memoria per dati serializzati. È prevedibile una riduzione del 50% circa dei requisiti di archiviazione. Il numero specifico dipende da i tuoi dati.

prestazioni di deserializzazione è almeno alla pari con il serializzatore standard di PHP. Le prestazioni di serializzazione dipendono dall'opzione "compact_strings" che abilita il tracciamento della stringa duplicato. Le stringhe vengono inserite in una tabella hash che aggiunge un sovraccarico. Negli scenari usuali questo non ha molto significato poiché il pattern di utilizzo è "serializza raramente, unserialize spesso". Con l'opzione "compact_strings" igbinary di solito è un po 'più lento del serializzatore standard. Senza di esso, un po 'più veloce.

Caratteristiche

  • appoggia stessi tipi di dati come il serializzatore standard di PHP: nullo, bool, int, float, string, array e oggetti.
  • __autoload & unserialize_callback_func
  • __sleep & __wakeup
  • -interface Serializable
  • la portabilità dei dati tra le piattaforme (32/64bit, endianess)
  • Testato su amd64 Linux, Linux ARM, Mac OSX x86, HP-UX PA-RISC e NetBSD sparc64
  • Collega alla cache OPC opcode come gestore di serializzazione (APC 3.1.7+)
  • Compati BLE con PHP 5.2 e 5,3

Speranza che aiuta

Problemi correlati