2009-05-12 17 views
6

Ho difficoltà a capire perché la codifica sicura di Java sia importante. Ad esempio, perché è importante dichiarare le variabili private? Voglio dire, capisco che renderà impossibile accedere a quelle variabili dall'esterno della classe, ma potrei semplicemente decompilare la classe per ottenere il valore. Analogamente, definire una classe come definitiva renderà impossibile la sottoclasse di questa classe. Quando la sottoclassificazione di una classe può essere pericolosa per la sicurezza? Ancora una volta, se necessario, potrei decompilare la classe originale e reimplementarla con qualsiasi codice dannoso che potrei desiderare. Il problema si presenta quando le applicazioni sono "attendibili" dall'utente? E le persone potrebbero quindi abusare di questa fiducia in qualche modo? Fondamentalmente quello che sto cercando è un buon esempio del perché le linee guida di codifica sicure dovrebbero essere seguite.Perché la codifica java secure è importante?

risposta

15

La programmazione è difficile.

Se si definiscono API rigorose, che non espongono le variabili che non dovrebbero essere esposte (ci piace chiamare questo encapsulation), si aiutano gli utenti delle proprie API, e quindi semplificano la programmazione. Questo è considerato una buona cosa.

Le ragioni non sono principalmente "sicurezza", come nel tenere segrete le cose segrete, quanto chiarezza, semplicità e comprensibilità.

Come bonus, è molto più semplice far funzionare le cose correttamente se si può sapere che l'utente dell'API non sta cambiando le "tue" variabili dietro le spalle, ovviamente.

+1

perché l'incapsulamento viene sempre spiegato in termini di sicurezza, quindi? Inoltre, perché l'incapsulamento facilita la programmazione? – JDelage

4

È "sicuro" che significa che un lavoro interno di classe è nascosto a chiunque lo usi.

Il termine secure non viene utilizzato come in "protezione di un server" viene utilizzato per indicare il fatto che un utente di una classe non deve preoccuparsi di come la classe eseguirà l'attività che desidera.

Prendendo il tuo esempio:

Esponendo le variabili di una classe avrebbe permesso l'utente della classe sapere della loro esistenza, che è qualcosa che non si vuole, ad esempio: basta premere un pulsante per accendere il luce, non è necessario ora che all'interno ci sia rame o whater di cui ha bisogno per eseguire l'operazione.

+0

Interessante! Finalmente una buona spiegazione della "sicurezza" in questo contesto. Le variabili protette – Jackson

1

Giusto per aggiungere quello che altri hanno già detto: alcune di queste funzionalità possono anche essere semplicemente considerate come un modo per dichiarare l'intenzione. Se faccio un membro private, lo rendono "impossibile" per gli altri di accedervi (è possibile, ma questo è oltre il punto qui), ma, cosa più importante, dico agli utenti che questo è un dettaglio di implementazione, che non dovrebbero fare affidamento su .

3

Ci sono due problemi qui.

Il primo quando si dichiarano le variabili come protette o private, esse non diventeranno parte della tua API pubblica. Altre classi potrebbero dipendere dalla tua classe in futuro, ed è importante che tu sia libero di cambiare il più possibile se vuoi includere nuove funzionalità, migliorare le prestazioni, ecc. Se tutti i tuoi valori sono pubblici di tutti i tuoi interni valori e meccanismi sono pubblici. Cambiarle potrebbe rompere altre classi che dipendono dalla tua.

Il secondo è che quando si espongono le variabili consente ad altre classi di modificare i valori. Se cambiano i valori interni se possono interrompere il programma e creare strani comportamenti imprevisti. Se crei un sistema che si basa sul rendimento accurato di una tua classe, e i valori interni sono cambiati, allora non puoi più fare affidamento su quel sistema. La sottoclasse rende questo più complicato. Il tuo sistema può fare affidamento su una classe di un certo tipo per eseguire azioni previste.Per sottoclassi è possibile creare una nuova classe che sembra essere dello stesso tipo ma non esegue le azioni previste.

Ad esempio, se si dispone di un quadrato di classe con una funzione protetta getArea(), si prevede di restituire l'area di un quadrato. Tuttavia, è possibile creare una nuova classe che si estende in quadrato, ad esempio il rettangolo di classe si estende in quadrato. Ora il rectange può scavalcare getArea(), ma è ancora di tipo square, che può rompere qualcosa che dipende da quella funzionalità di square. Rendendo il tuo finale di classe stai affermando che questo non può mai accadere nel tuo sistema.

Questo tipo di "codifica sicura" non impedirà a qualcuno di vedere il codice sorgente, ma aiuta a rendere il codice più affidabile e utilizzabile in futuro.

+0

fanno parte dell'API pubblica. Utilizzare private o, se necessario, alcune variabili di accesso predefinite "pacchetto privato". –

4

Java è un linguaggio object-oriented programming e uno dei concetti chiave nella programmazione orientata agli oggetti è encapsulation.

L'idea dietro l'incapsulamento è quella di "nascondere" i dettagli di implementazione come le variabili interne che mantengono lo stato dell'oggetto e il funzionamento interno come gli algoritmi e forniscono solo un'interfaccia che altri oggetti possono utilizzare per eseguire funziona con l'oggetto.

Utilizzando tale concetto, si desidera nascondere gli stati interni utilizzando le variabili private per impedire che altri oggetti influiscano direttamente sugli stati interni. In Java, è comune vedere getter e setter (ad esempio getColor e setColor) per lavorare con gli oggetti.

Inoltre, l'incapsulamento può aumentare la robustezza del codice.

Ad esempio, limitando l'accesso agli stati interni, è possibile eseguire alcuni controlli di integrità prima che un oggetto venga modificato.

Come esempio solida, dire c'era un oggetto Score che doveva avere un valore percent tra 0 e 100. Fornendo un metodo setPercent(int) che convalida che il valore specificato era compreso nell'intervallo consentito, impedirebbe che l'oggetto Score venisse impostato in uno stato inaccettabile.

Così, cercando di manipolare direttamente lo stato interno scrivendo una dichiarazione come score.percent = 150 potrebbero essere evitati, se il metodo setPercent causa un errore o genera un Exception se il valore specificato è inaccettabile.

1

immagina solo se il tuo oggetto ha una proprietà interna che non è privata (nascosta) e il tuo codice che accede a questa proprietà è eseguito in ambiente multithreading, quindi N thread inizieranno ad accedervi contemporaneamente, 5 thread vorrebbe cambiare questo proprietà, 4 da leggere. Non è possibile in alcun modo assicurarsi che le cose funzionino correttamente, né i thread sapranno quali dati detengono in quel momento e sono stati modificati con successo le proprietà di quell'oggetto.

Dovrai programmare un pezzo di codice speciale che sarà responsabile per gestire l'accesso sincrono e tuttavia non sarà garantito che il tuo codice funzionerà correttamente dal momento che devi ancora controllare il resto di 680 classi nel tuo programma accedendo a quella proprietà non per accedervi direttamente.

In breve, ci si trova in un problema enorme, e il debug è un incubo dal momento che non si sa quando i dati sono stati chagned, quale thread ha fatto, da dove si gionro ecc

Solo uno scenario di ciò sta succedendo se non incapsuli ...

Per fortuna, il tuo codice viene eseguito all'1% più veloce, c'è meno carico sullo stack, hai ottenuto guadagni di prestazioni probabilmente trascurabili che pagherai con arresti periodici del sistema e minori possibilità di debug di successo.

1

Il termine "codifica sicura" si riferisce alla costruzione di software che tenta chiaramente di evitare vulnerabilità di sicurezza, sia in linguaggio C, Java, Ruby, assembly, o qualsiasi altra cosa. Forse la parte più centrale di questo, dopo aver selezionato un sistema di linguaggio sicuro, è di mantenere buone pratiche di programmazione. Se un programma non è chiaro, hai poche possibilità di essere degno di fiducia.

Per Java ci sono due guide di rilievo:

In Java esistono due modalità distinte di codifica sicura.

In uno si ha a che fare con codice che potrebbe non avere tutti i privilegi che il proprio codice fa. Ad esempio se stai scrivendo una libreria o un codice di firma devi farlo. Dovrebbe essere impossibile che il codice dannoso sfrutti le tue autorizzazioni in modi involontari. Questo è difficile!

Più comunemente si tratta di programmi che trattano solo dati non attendibili. Ad esempio, i server Web (si pensi all'iniezione di XSS e SQL) e ai programmi applicativi desktop che trattano file non attendibili (di solito il problema è che il codice C ha buffer overflow - il C++ autentico è migliore). In alcune situazioni, la negazione del servizio (DoS) può essere un problema grave.

C'è qualche sovrapposizione. Per esempio gli interpreti corrono con i permessi del codice dell'interprete e possono essere abbastanza "potenti".

Problemi correlati