2015-12-11 7 views
8

Leggendo il codice sorgente per Instant di classe, mi sono imbattuto in questo metodoChe cosa significa il metodo Instant.readObject "Difendi [s] contro flussi dannosi"?

/** 
* Defend against malicious streams. 
* 
* @param s the stream to read 
* @throws InvalidObjectException always 
*/ 
private void readObject(ObjectInputStream s) throws InvalidObjectException { 
    throw new InvalidObjectException("Deserialization via serialization delegate"); 
} 

La descrizione mi ha incuriosito. Che cos'è un "flusso malevolo"? E come si difende questo metodo contro di esso?

+0

A "flusso dannoso" è uno che avrebbe fatto un decoder ingenuo fare qualcosa di brutto come allocare un enorme quantità di memoria o crash. –

+0

Perché non postare una risposta? Sembra un argomento interessante –

+1

Si noti che non è specifico per 'Instant'. 'LocalDateTime',' LocalDate' e altri hanno anche questo. – Tunaki

risposta

6

Instant e altre classi java.time, vengono serializzate utilizzando un delegato con scope del pacchetto - java.time.Ser. Vedere il metodo writeReplace per vedere come viene creato il delegato.

Come tale, l'unico modo in cui è possibile chiamare il metodo readObject è se qualcuno sta passando in un flusso dannoso (uno creato con l'unico scopo di provare a creare un oggetto non valido). L'eccezione garantisce che tali flussi dannosi siano bloccati.

In generale, ogni volta che viene utilizzato un delegato di serializzazione, è consigliabile prendere in considerazione il blocco di readObject in questo modo.

4

Joshua Bloch l'autore di "Efficace Java" ha introdotto his idea sul modello del proxy di serializzazione. Sfondo molto illuminante per la tua domanda.

Con questo metodo writeReplace in atto, il sistema di serializzazione sarà mai generare un'istanza serializzato della classe che racchiude, ma un attaccante potrebbe realizzare uno nel tentativo di violare la classe invarianti. Per garantire che un tale attacco avrebbe fallito, semplicemente aggiungere questo metodo readObject alla classe racchiude ...

// readObject method for the serialization proxy pattern 
private void readObject(ObjectInputStream stream) throws InvalidObjectException { 
    throw new InvalidObjectException("Proxy required"); 
} 
+0

Ottimo! Quel libro è un capolavoro, merita sicuramente una lettura accurata ... –