Nelle ultime versioni Java c'è stata una modifica che forse è passata inosservata e che giustamente è il caso di sottolineare, come fa un
articolo di
Xueming Shen.
Tale modifica riguarda la codifica
UTF-8 e in particolare il rifiuto della
non-shortest-form. Infatti l'interpretazione di questa forma particolare di rappresentazione può essere utilizzata da exploit di vario tipo per ottenere dati sensibili. I dettagli inerenti questa problematica sono ben descritti in un
corrigendum, ma vediamo molto brevemente cosa significa.
Senza scendere troppo nei dettagli, la codifica
UTF-8 di caratteri
Unicode si basa su una serie di
bit pattern; a seconda di quanti byte si voglio rappresentare è possibile avere più di una forma per uno stesso carattere
Unicode. Sicuramente è più facile fare un esempio che dire tante parole. Ecco, appunto, la rappresentazione della stringa ABC utilizzando un solo byte:
0x41 0x42 0x43
e utilizzandone due:
0xc1 0x81 0xc1 0x82 0xc1 0x83
Quest'ultimo è proprio un caso di
non-shortest-form, poiché rappresentiamo con una sequenza ridondante un carattere
Unicode che andrebbe bene anche usando la sua forma più breve. Per avere altri esempi riportiamo il seguente stralcio di codice in grado di mettere a confronto la
non-shortest-form con due byte e il carattere rappresentato.
byte[] bb = new byte[2];
for (int b1 = 0xc0; b1 < 0xc2; b1++) { for (int b2 = 0x80; b2 < 0xc0; b2++) { bb[0] = (byte)b1;
bb[1] = (byte)b2;
String cstr = new String(bb, "UTF-8");
char c = cstr.toCharArray()[0];
System.out.printf("[%02x, %02x] -> U+%04x [%s]%n", b1, b2, c & 0xffff, (c>=0x20)?cstr:"ctrl");
}
}
Il
corrigendum citato evita il crearsi di questa situazione, specificando qual è la
shortest form da usare e impedendo il verificarsi di più
non-shortest-form. Ciò previene possibili vulnerabilità dovute a questa differente codifica. Tale nuova interpretazione della codifica
UTF-8 è compatibile con le ultime versioni Java: JDK7, Open JDK 6, JDK 6 update 11 e successive, JDK5.0u17 e 1.4.2_19. Chi fosse invece curioso di vedere la sua interpretazione in codice, ecco un
confronto tra la nuova e la vecchia versione della classe
UTF_8.