2013-03-07 9 views
14

Sono nuovo di Java e quando ho imparato, mi sono imbattuto nel fatto che uno String è immutabile. Durante la lettura del motivo, sono emersi alcuni motivi, ad esempio l'aumento delle prestazioni, poiché il suo valore non può essere modificato e può essere condiviso da più thread. Queste ragioni lo capisco.
Ma non capisco come sia collegato alla sicurezza. In che modo un String è un aiuto immutabile nella sicurezza Java?In che modo la stringa Java è immutabile e aumenta la sicurezza?

Per favore aiutatemi a capire. Grazie in anticipo.

+2

Dove dice che aiuta per la sicurezza? – ivant

+0

possibile duplicato di [Java Inheritance, in che modo l'estensione di una classe influenza la classe effettiva] (http://stackoverflow.com/questions/15165619/java-inheritance-how-does-a-extending-a-class-effect- the-actual-class) – jtahlborn

risposta

15

una pratica molto comune in librerie di classi scrittura è la memorizzazione dei parametri passati nella vostra API, per esempio, in un costruttore, come questo:

public class MyApi { 
    final String myUrl; 
    public MyApi(String urlString) { 
     // Verify that urlString points to an approved server 
     if (!checkApprovedUrl(urlString)) throw new IllegalArgumentException(); 
     myUrl = urlString; 
    } 
} 

Were String mutabile, questo porterebbe a un sottile exploit: un utente malintenzionato passerebbe un buon URL, attenderà qualche microsecondo, quindi imposta l'URL in modo che punti a un sito di attacco.

Poiché la memorizzazione senza copiare è una pratica ragionevolmente comune e poiché le stringhe sono tra i tipi di dati più comunemente usati, lasciare le stringhe mutabili aprirebbe molte API che non sono state ancora scritte per un serio problema di sicurezza. Rendere immutabili stringhe chiude questo particolare buco di sicurezza per tutte le API, incluse quelle che non sono ancora state scritte.

+1

Un buon esempio di mutabilità ("parziale") è 'File'. Essenzialmente si limita a racchiudere un 'String'. Tuttavia ci sono stati un certo numero di casi in cui è stato utilizzato per un controllo di sicurezza. Una sottoclasse maliziosa può cambiare il controllo e l'uso (TOCTOU/TOC2TOU vulnerabilità). –

+1

Non sono sicuro di come siano fatti gli exploit sottili, ma supponendo che il metodo venga intercettato in qualche modo tramite un altro thread. In sostanza, poiché String è immutabile se il costruttore MyApi viene chiamato con urlString "ABC", i contenuti non possono essere modificati dall'esterno del costruttore. Se non fosse immutabile, potrebbe essere mutato sull'altro thread semplicemente chiamando urlString = "someMaliciousUrl"; dopo la chiamata checkApprovedUrl. Questa comprensione è corretta? – Mercury

+0

@Mercury Sì, questa è la corretta comprensione dell'attacco descritto sopra. – dasblinkenlight

0

La stringa è immutabile significa che non è possibile modificare l'oggetto stesso, ma è possibile modificare il riferimento, naturalmente. Quando si chiama (ad esempio) a = "ty", si sta effettivamente cambiando il riferimento di a a un nuovo oggetto creato dal letterale stringa "ty". La modifica di un oggetto vuol dire utilizzare i suoi metodi per modificare uno dei suoi campi, per esempio:

Foo x = new Foo("the field"); 
x.setField("a new field"); 
System.out.println(x.getField()); // prints "a new field" 

mentre in una classe immutabile (dichiarata come finale), per esempio String, non è possibile modificare la stringa corrente, ma è possibile tornare una nuova stringa, vale a dire:

String s = "some text"; 
s.substring(0,4); 
System.out.println(s); // still printing "some text" 
String a = s.substring(0,4); 
System.out.println(a); // prints "some" 
+4

"final" non significa che sia immutabile. Per le classi vuol dire che non puoi ereditarlo. – ivant

+0

per essere immutabile devi essere definitivo in modo che la tua sottoclasse non rotti immutabilità – topcat3

+0

che potrebbe essere il caso, ma non è sufficiente dichiararlo definitivo per renderlo immutabile. – ivant

3

Per il concetto SecurityManager sono necessarie stringhe immutabili. dasbklinkenlight è già sulla strada giusta con la sua risposta, ma le stringhe mutabili interromperanno completamente il concetto di sandbox.

Ad esempio, quando si fa un new FileInputStream("foo"); per leggere un file, l'attuazione API internamente fare tra gli altri:

  • richiamare il metodo checkRead del manager di sicurezza con "pippo" come argomento e gettare un'eccezione se il controllo ha esito negativo
  • sistema operativo
  • uso chiama per aprire effettivamente il file se il controllo di sicurezza ha approvato

Se l'invoker è in grado di modificare la stringa tra questi due passaggi, il controllo di sicurezza può riuscire per una file, mentre in realtà verrà aperto un altro file.

+0

non sono sicuro Se ho capito correttamente ho un dubbio dal momento che java passa per il controllo di sicurezza del valore è successo per foo solo foo sarà aperto –

Problemi correlati