RICERCA DI PATTERN E VALIDAZIONE DELLE STRINGHE (ANCHE ESPRESSIONI REGOLARI).
PRIMA PARTE:
Su questo argomento ho trovato molte cose sparse per la rete. Tuttavia trattavano in modo sommario l'argomento del titolo. In questo pillolotto descriverò (o meglio tenterò di...) spiegare nel modo più semplice possibile come gestire le stringhe per renderle valide a dei parametri da noi settati (ovvero renderle conformi ad un pattern). Le tecniche prese in esame sono utili per validare l'input dei form e per controllare i campi che vengono passati ad una query, prevenendo in modo abbastanza certo l'SQL injectiono l'inserimento di codice “malevolo” nel form o nella query-string del browser. L'argomento “sicurezza” preso in oggetto quindi è circostanziato al passaggio che avviene tra form e query a livello di PHP. Eventuali controlli sulle sessioni e sul database (che avvengono rispettivamente prima e dopo questo passaggio) non sono trattate. Dovete cercare quindi qualche altra pillola per l'argomento affinchè sia chiaro come gestire in modo sicuro tutto il processo.
Un argomento correlato a questo lo potete trovare qui http://forum.html.it/forum/showthrea...hreadid=392715
Ok, partiamo subito con un esempio:
codice:
<?php
$frase="ciao mondo, come va oggi pomeriggio?";
$mio_array=explode(" ", $frase);
foreach($mio_array as $parola_da_cercare){
if($parola_da_cercare == "oggi") echo "oggi è stato trovato";
}
?>
Questo script fa una cosa semplicissima: prende una frase e la salva in una variabile ($frase). Poi creo una variabile $mio_array (che dovrà contenere i “pezzi” della frase che sto cercando).
A $mio_array assegno la funzione explode(9 che prende due parametri: il primo è detto delimitatore mentr il secondo è la frase che voglio far “esplodere” nelle sue parti. Explode(), in sostanza scompone la mia frase in tante parole che sono delimitate da uno spazio (il mio delimitatore).
Poi facendo un ciclo ricerco nell'array la parola specificata (in questo caso l'ho scritta direttamente ma poteva benissimo provenire da un form...che poi validerò). Se la parola esiste mi stampa una frase.
Per controllare effettivamente la funzione explode (cioè, come opera) provate a scrivere questo esempio
codice:
<?php
$frase="ciao mondo, come va oggi pomeriggio?";
$mio_array=explode(" ", $frase);
foreach($mio_array as $parola_da_cercare){
if($parola_da_cercare == "oggi") echo "'oggi' è stato trovato
";
else echo "- non ho trovato la parola cercata
";
}
?>
Questo esempio mostra come il ciclo confronti effettivamente le parole dell'array (esploso) e la parola della mia ricerca (contenuta nell'istruzione if).
Questo è il risultato:
- non ho trovato la parola cercata
- non ho trovato la parola cercata
- non ho trovato la parola cercata
- non ho trovato la parola cercata
'oggi' è stato trovato
- non ho trovato la parola cercata
fate caso che la riga trovata è la quinta (anche nella frase la parola “oggi” è al quinto posto, se calcoliamo che ogni parola occupa un posto).
Il problema però nasce quando vogliamo trovare una parola specifica. Ma come? E fino adesso che abbiamo fatto?! :-) Le parole esplose si portano dietro tutta la punteggiatura. Se trasformate infatti “pomeriggio?” in “pomeriggio ?” noterete che le righe ora sono 7. Php quindi tratta ogni singola porzione di caratteri delimitati dagli spazi come una parola (e quindi anche un sinologp unto di domanda o una virgola). Il nostro esempio non funziona ricercando la parola “mondo”, perchè contiene la virgola.
La funzione ereg() invece cerca ESATTAMENTE la frase che passate come parametro.
Questo esempio fa la stessa cosa dell'array esploso con il ciclo senza badare alla punteggiatura:
codice:
<?php
$frase="ciao mondo, come va oggi pomeriggio?";
if(ereg("mondo", $frase)) echo "'mondo' è stato trovato
";
?>
usando gli array aggiungo un parametro ad ereg()
codice:
<?php
$frase="ciao mondo, come va oggi pomeriggio?";
if(ereg("mondo", $frase, $mio_array)) echo "$mio_array[0] è stato trovato
";
?>
il terzo parametro di ereg() salva il risultato in un array con nome arbitrario. La stringa cercata quindi avrà indice 0 (come già sapete, l'array parte da 0 e non da 1).
Ora arriva il bello. Cosa c'entrano questi esempi con la sicurezza? Immaginate questo: un utente compila un form con i suoi dati, o un login per autenticarsi in un'area riservata. Potrebbe passare qualsiasi parametro
Ad esempio un mancato controllo ad un form potrebbe passare un istruzione SQL creando un'autenticazione fittizzia. Molti conosceranno un esempio del tipo 'A' OR 'B'='B'.
Questa istruzione SQL fa una cosa molto semplice: logga chi compila il form perchè alla funzione viene passata un'istruzione legittima (infatti il modulo non controlla che ci siano parametri cazzuti passati).
Quindi il controllo non lo fa più la funzione ma l'istruzione passata. Questo bisogna prevenirlo. Consiglio una lettura della pillola sull'SQL injection a completezza di questa.
I caratteri “riservati” a PHP che non possono essere cercati sono:
() [] {} | \ $ . * ? + ^
Se volete usare questi parametri in una ricerca per delimitare la stringa dovete semplicemente anteporre una barra rovesciata. Il carattere speciale diventerà una semplice stringa. Quindi per delimitare la parola/lettera $ fate ereg(“$”, “oggi ho preso molti \$”) e così via...
Ad esempio:
codice:
<?php
$frase="oggi sono senza soldi per la cena";
$corrispondenza="soldi....";
if(ereg($corrispondenza, $frase, $mio_array)) echo "'$mio_array[0]' è stato trovato
";
?>
Darà come risultato: 'soldi pe' è stato trovato .
Mentre scrivendo così $corrispondenza="soldi\.\.\.\.", non da un bel niente. Se la frase contiene la stringa soldi.... allora viene trovata.
Chiarito questo semplice aspetto delle stringhe (i caratteri speciali) torniamo andiamo avanti con il controllo sulle stringhe.
Vogliamo prevenire l'inserimento di qualsiasi carattere che non ci piace ed in più vogliamo essere sicuri che non vengano inserite cazzate nei form.
Per far validare una stringa stringa si possono negare od accettare dei caratteri. I caratteri messi tra parentesi quadra sono accettati mentre quelli preceduti dal simbolo ^ non lo sono.
Ad esempio
Sto cercando dentro una frase
codice:
<?php
$frase="oggi sono contento";
$corrispondenza="content[oa]";
if(ereg($corrispondenza, $frase, $mio_array)) echo "'$mio_array[0]' è stato trovato
";
?>
se nella frase metto contenta vengono accettate le ricerche. Se il mio esempio ha invece
codice:
$corrispondenza="content[^oa]";
La frase non viene trovata perchè sto dicendo a php di trovare tutte quelle parole che uguali a content che NON finiscano con a oppure o. Se mettessi “contenti funzionerebbe.
Questo piccolo esempio è embrionale per capire che cosa si vuole accettare in una stringa.
Un metodo semplice per far accettare le stringhe è quello di utilizzare le scorciatoie. Poi le vediamo