Prima di tutto "la codifica ASCII UTF-16" è una contraddizione, poiché UTF-16 e ASCII sono schemi di codifica esclusivi. Ma presumibilmente si sta solo riferendo all'utilizzo di Unicode per bypassare i meccanismi di filtraggio.
Il principio generale è questo: spesso pensiamo ai caratteri codificati in ASCII - "A" è il numero 65, "z" è il numero 122. Ma non è l'unico schema di codifica dei caratteri; perché il mondo usa più dell'alfabeto inglese, dobbiamo rappresentare molti più personaggi di questo. Quindi, Unicode, che ha rappresentazioni per quasi tutti i personaggi in ogni lingua mai scritta, da Sinhala a Klingon.
Rappresentare tutti quei personaggi (circa 1,1 milioni possibili, non tutti in uso) in una forma numerica è una vera sfida. Potresti usare 32 bit, ma è uno spreco di spazio dato che 3 dei 4 byte di solito sono zero. È possibile utilizzare una lunghezza variabile, ma non è possibile eseguire operazioni di sottostringa costanti. Esistono quindi numerosi standard, uno dei quali è UTF-16 (che probabilmente hai indovinato utilizza caratteri a 16 bit).
Non tutti i programmatori sono abituati all'idea di gestire più set di caratteri, anche se il framework sottostante li supporterà spesso. Quindi, a volte le regole di filtro o le precauzioni saranno stabilite usando l'ipotesi che i caratteri saranno rappresentati in UTF-8 o ASCII, che di solito sono.
Quindi il filtro cerca una data stringa, ad esempio \"
per esempio, che in ASCII e UTF-8 corrisponde allo schema {92,34}. Ma in UTF-16 sembra diverso; in realtà è {0,92,0,34}, che è semplicemente abbastanza diverso da essere filtrato da un filtro che non se lo aspettava.
E sebbene il filtro non comprenda UTF-16, il framework sottostante lo fa, quindi il contenuto viene normalizzato e interpretato proprio come qualsiasi altra cosa, consentendo alla query di continuare senza filtrare.
MODIFICA PER AGGIUNGERE:
Si noti che PHP è eccezionalmente scarso nella gestione delle codifiche dei caratteri; e semmai, questo sta minimizzando il problema. PHP considera di default tutte le stringhe come ASCII, ovvero le funzioni interne come strstr
e preg_replace
assumono semplicemente che tutte le stringhe siano codificate in ASCII. Se ciò sembra pericolosamente inadeguato, è perché lo è. Ma a loro difesa, ricordiamo che PHP precede UTF-16 di circa un anno, e tutto questo è apparentemente risolto nella versione 6 di PHP.
Nel frattempo, la libreria mbstring è stata creata per risolvere questa lacuna, ma non è né ampiamente utilizzata né sottosviluppata. Se sei abbastanza fortunato da avere questa estensione a tua disposizione, puoi utilizzare mbstring.overload nel file php.ini per forzare la sostituzione delle funzioni interne di elaborazione delle stringhe con alternative multibyte-aware. Questo può anche essere attivato utilizzando la direttiva php_admin_value
nei file .htaccess
.
Un'altra funzione utile è mb_internal_encoding , che imposta la codifica usata internamente da PHP per rappresentare stringhe. Usando una codifica interna compatibile con Unicode, puoi alleviare un po 'di cattiveria. Almeno un riferimento che ho letto (ma purtroppo non riesco a trovarlo ora) suggerisce che impostando la codifica interna su UTF-8, si abilita un'ulteriore elaborazione sulle stringhe in entrata che li normalizza su una singola codifica. D'altra parte, almeno un altro riferimento suggerisce che PHP si comporta in modo stupidamente possibile a questo proposito, e semplicemente trascina i dati non modificati indipendentemente dalla codifica, e ti consente di affrontare le conseguenze. Mentre il primo ha più senso, con quello che so su PHP, penso che quest'ultimo sia altrettanto probabile.
Come alternativa finale; e menziono questo solo in parte per scherzo, è semplicemente non usare PHP e invece adottare un'architettura migliore. È difficile trovare un framework così popolare che abbia così tanti problemi fondamentali come PHP. Il linguaggio, l'implementazione, il team di sviluppo, l'architettura dei plugin, il modello di sicurezza - è davvero un peccato che PHP sia così ampiamente implementato. Ma questa è, ovviamente, solo un'opinione.