2013-07-24 4 views
6

Ho visto una risposta da un'altra post:Perché le stringhe mutabili possono causare problemi di sicurezza?

La stringa è stata ampiamente utilizzata come parametro per molte classi java, ad es. per aprire la connessione di rete, per aprire la connessione al database, aprire i file. Se String non è immutabile, ciò comporterebbe gravi minacce alla sicurezza.

Penso che controllare la stringa prima dell'uso risolverà il problema. Perché è una ragione per cui la stringa è progettata per essere immutabile?

Qualcuno può darmi un esempio di codice concreto?

+3

"Penso che controllare la stringa prima di noi e risolverebbe il problema "A meno che tu non usi esplicitamente una sorta di serratura, no. –

+0

Se implementato in modo improprio, cosa impedisce a un trasgressore di modificare il riferimento dell'assegno? – Gamb

+0

Ci sono molte ragioni per cui la stringa è progettata per essere immutabile, capire l'immutabile in questo modo: * quando una classe è indipendente e completamente concreta nella natura. * – Azad

risposta

4

In generale, è più facile scrivere e rivedere il codice sensibile quando i valori non cambiano , perché ci sono meno intrecci di operazioni che potrebbero influenzare il risultato.

Immaginate codice come

void doSomethingImportant(String name) { 
    if (!isAlphaNumeric(name)) { throw new IllegalArgumentException(); } 
    Object o = lookupThingy(name); 
    // No chance of SQL-Injection because name is alpha-numeric. 
    connection.executeStatement("INSERT INTO MyTable (column) VALUES ('" + name + "')"); 
} 

Il codice fa alcuni controlli per evitare un'escalation di autorità, ma questo solo se il isAlphaNumeric(name) è vero quando l'argomento di executeStatement è chiamato.

Se le prime due dichiarazioni sono state riordinate, questo non sarebbe un problema, quindi l'insicurezza nasce, in parte, da un cattivo interleaving. Ma altri codici potrebbero chiamare questa funzione e assumere che name non venga modificato da esso, quindi potrebbe dover eseguire e rieseguire i controlli di validità.

Se String non è immutabile, potrebbe essere stato modificato da lookupThingy. Per essere sicuri che il controllo di sicurezza funzioni, c'è una quantità molto maggiore di codice che deve essere eseguita correttamente affinché questo codice sia sicuro contro l'iniezione SQL.

Non solo la quantità di codice che deve essere eseguita correttamente è maggiore, ma un manutentore che apporta modifiche locali a una funzione potrebbe influire sulla sicurezza di altre funzioni molto lontano. Gli effetti non locali rendono difficile la manutenzione del codice. Mantenere le proprietà di sicurezza è sempre rischioso dal momento che le vulnerabilità della sicurezza sono raramente ovvie, quindi la mutabilità può portare al degrado della sicurezza nel tempo.


Perché è una ragione che corda è realizzata per essere immutabili?

Questo è separato dal motivo per cui è una cattiva sicurezza.

È opinione diffusa che programmi scritti in lingue con tipi di stringa immutabili prontamente disponibili eseguano meno copie di buffer non necessarie rispetto a quelle che non lo sono. Le copie di buffer non necessarie consumano memoria, causano un abbandono del GC e possono causare semplici operazioni su input di grandi dimensioni per prestazioni molto peggiori rispetto a quelle su input piccoli.

Si ritiene inoltre che sia più facile scrivere programmi corretti quando si usano stringhe immutabili, poiché è improbabile che non si riesca a copiare in modo difensivo un buffer.

+3

O peggio, forse la Stringa è visibile a un'altra discussione, che potrebbe quindi cambiare la sua valore tra la verifica dell'integrità e l'uso - anche senza una chiara richiesta di intervento! –

+0

@HenryKeiter, buon punto. –

2

È la più vecchia parodia di sicurezza nel libro: presentare qualche parm al sistema operativo, farlo convalidare il parm, quindi aggiornare il parm mentre il sistema operativo si riferisce al parm, quindi farà cose diverse da quello verificato .

Questo è stato utilizzato per rompere IBM OS/360 negli anni '60: Per richiedere l'I/O del disco si passava al sistema operativo un "programma di canale" che conteneva l'indirizzo del disco e l'indirizzo di memoria e altre cose. Il sistema operativo verificava che il disco e gli indirizzi di memoria fossero posizioni in cui eri autorizzato, quindi passava quel "programma di canale" all'hardware del canale I/O da eseguire, senza prima fare una copia locale. Non è stato difficile cronometrare le cose in modo da modificare il programma di canale dopo che era stato controllato ma prima che l'hardware del canale I/O lo eseguisse, consentendo l'accesso a dischi e memoria non autorizzati.

(Tenete presente che in questo lasso di tempo la memoria era molto preziosa, quindi non copiare il programma di canale ha salvato una quantità non trascurabile di memoria, ma questa scappatoia è stata rapidamente chiusa quando il modo di sfruttarlo è diventato abbastanza noto.)

(Naturalmente, si deve chiedere se qualsiasi programma Objective-C può essere considerato "sicuro" da altro codice in esecuzione nello stesso processo. la natura "duck typing" di Objective-C rende vera improbabili sicurezza a L'uso di stringhe immutabili è più una protezione dalle modifiche accidentali che dalle modifiche dannose.)