Dopo aver letto le altre risposte, mi si avvicinò con questa soluzione:
public static boolean isParent(File parent, File file) {
File f;
try {
parent = parent.getCanonicalFile();
f = file.getCanonicalFile();
} catch(IOException e) {
return false;
}
while(f != null) {
// equals() only works for paths that are normalized, hence the need for
// getCanonicalFile() above. "a" isn't equal to "./a", for example.
if(parent.equals(f)) {
return true;
}
f = f.getParentFile();
}
return false;
}
Quindi l'utilizzo sarebbe:
File file = new File(folder, path);
if(! isParent(folder, file)) {
... deny access ...
}
Il codice sopra probabilmente non è molto veloce ma tutte le altre soluzioni hanno problemi di sicurezza:
Posso rimuovere /../|^../|/..$
ma non funzionerebbe su Windows. Per Windows, il modello sarebbe diventato più complesso e non dimenticate che Java accetta /
come separatore di file in Windows (sì, C:/Windows/
è valido e lo stesso significato di C:\Windows\
)
Inoltre, il percorso a/../b/c
è valida dal momento che doesn Rompere il confine, quindi basta rimuovere i movimenti relativi non è abbastanza buono.
È possibile creare due stringhe utilizzando getCanonicalPath()
e verificare che il percorso parent
sia un prefisso file
. Ma poi, dovrei assicurarmi che il carattere dopo il percorso genitore sia un separatore di file (vedi sopra perché File.SEPARATOR
non è abbastanza).
fonte
2013-04-24 09:53:30
questo tipo di sicurezza è fatto da permessi dei file, il motivo per cui si ha bisogno in Java? – Dima
È sufficiente mantenere la _black folder list_ e assicurarsi che il percorso non sia nell'elenco? – Michael
Poiché alcuni file interessanti potrebbero dover essere letti sul server ma non sulle applicazioni in esecuzione su di esso. Leggere '/ etc/passwd' non è un buco di sicurezza da solo - non danneggia nulla ma le informazioni apprese rendono più facile attaccare il sistema. –