Il logo del sito

Appunti su PHP

PHP Form - Validation

COMPLETA - Sembra che il codice php funzioni, sono però sicuro che le cose si possono fare diversamente. In ogni caso, questo è un esempio importante che si sviluppa per quattro lezioni di w3Schools

PHP - La sicurezza innanzia a tutto.

L'esempio l'ho preso da w3schools PHP 5:Form Validation, Form Required, URL / E-mail e Form Complete,

La corretta validazione dei dati è fondamentale per proteggersi da haker e spammers.

Name:          
E-mail:        
SitoWeb:       
Genere:       FemminileMaschile
Submit: 

Regole di convalida

  • Nome Richiesto + Deve contenere solo lettere e spazi;
  • E-mail Richiesto + Deve contenere un indirizzo email valido (con @ e .);
  • Sito Web Opzionale, Se presente deve contenere un URL valido;
  • Osservazioni Opzionale, textarea
  • Genere Richiesto

Il tuo input

/TestPages/php_03.php





L'elemento Form

L'HTML dell'elemento form è il seguente:

  <form method="post" action="<?php echo htmlspecialchars ($_SERVER["PHP_SELF]);?>">

$_SERVER["PHP_SELF"] è la variabile superglobal che restituisce il nome dello script in esecuzione. In questo modo i dati della form saranno inviati alla pagina stessa. In questo modo gli eventuali messaggi d'errore saranno visualizzati sulla stessa pagina della form.

htmlspecialchars() è una funzione che converte i carattere speciali in entità HTML. Questo significa che i caratteri < e > saranno sostituiti con &lt; e &gt; Questo impedisce ai malintenzionati di sfruttare il codice iniettando codice HTML o Javascript (attacchi Scripting Cross-site) nei moduli.

NOTA IMPORTANTE SULLA SICUREZZA PHP.

$_SERVER["PHP_SELF"] può essere usata dagli hakers. Un utente potrebbe inserire uno (/) e qualche comando Cross Site Scripting(XSS).

Quella nei confronti di XSS è un tipo di vulnerabilità web in quanto consente di inserire script lato client nelle pagine web visualizzate dagli utenti.

Supponiamo di avere il seguente codice in una pagina test_form.php:

  <form method="post" action="<?php echo ($_SERVER["PHP_SELF]);?>">

Ora, se un utente inserisce nella barra indirizzo del browser:

  http://www.example.com/test_form.php 

il codice html sopra mostrato sarà tradotto in:

  <form method="post" action="test_form.php"><

Fin qui tutto bene. Ma, consideriamo il caso che un utente inserisca il seguente URL nella barra degli indirizzi:

  http://www.example.com/test_form.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E

Nel mio caso:

  http://www.clamin.it/TestPages/php_03.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E

In questo caso, il codice sarà tradotto in:

  <form method="post" action="test_form.php">script>alert('hacked')</script>

Questo codice aggiunge una tag script ed un innocuo comando alert

Bisogna essere consapevoli che all'interno del tag scrip può essere inserito un qualsiasi codice JavaScript, anche dannoso.

Ho verificato che Chrome blocca comunque lo script, Internet Explore si accorge del tentativo di intrusione e non esegue l'alert, Firefox esegue l'alert ma si accorge dell'intrusione.

COME EVITARE CHE $_SERVER["PHP_SELF"] POSSA ESSERE SFRUTTATA.

Ci si può proteggere ricorrendo alla funzione htmlspecialchars() che converte caratteri speciali in entità HTML. Scrivendo:

  <form method="post" action="<?php echo htmlspecialchars ($_SERVER["PHP_SELF]);?>">

il codice di prima sarebbe convertito in:

  <form method="post" action="test_form.php /&quot;&gt; &lt;script&gt;alert('hacked')&lt;/script&gt;

che non fa nessun danno.

Ho verificato che Chrome blocca con le stesse modalità di prima, Internet Explorer e Firefox sembrano comportarsi esattamente come prima: Si accorgono dell'intrusione. Ma Firefox esegue lo stesso il comando alert.

VALIDAZIONE DEI DATI DELLA FORM CON PHP.

Abbiamo appena visto che occorre passere tutte le varibile inviate tramite la funzione htmlspecialchars()

Dobbiamo fare altre due cose:

  1. Rimuovere, dai dati di input, tutti i caratteri non necessari (extraspaces, tab, newline) con la funzione PHP trim()
  2. Rimuovere, dai dati di input, i backslashes(\) con la funzione PHP stripslashes
  3. Neutralizzare, nei dati di input, tutti i carattere speciali html
  4. Verificare che il campo nome contenga solo lettere e spazi
  5. Verificare che il campo email sia un indirizzo email valido
  6. Verificare che il campo website sia un URL valido

Il prossimo passo è creare una funzione, test_input() che che farà per noi tutti i controlli

1 - Rimozione dei caratteri non necessari

      $data = trim($data);
              
2 - Rimozione dei backslashes

      $data = stripslashes($data);
              
3 - Neutralizzazione dei caratteri html

      $data = htmlspecialchars($data);             
              
4 - Verifica che il nome contenga solo caratteri e spazi

      if (!preg_match("/^[a-zA-Z ]*$/",$name)) {
         $nameErr = "Only letters and white space allowed"; 
      }              
              
4 - Verifica dell'indirizzo email

      if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
         $emailErr = "Invalid email format"; 
      }             
              
5 - Verifica dell'URL del website

      if (!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i",$website)) {
         $websiteErr = "Invalid URL"; 
      }  
      
      /* oppure */
      
      if (!filter_var($website, FILTER_VALIDATE_URL)) {
         $websiteErr = "Invalid URL"; 
      }      
              

Il secondo metodo sembra essere più "esigente" del primo. Infatti da errore se manca http:// mentre per il primo metodo va bene iniziare con www.

In realtà non ho ben capito in cosa consista il controllo. Ho messo in serie i due controlli e se l'indirizzo inizia con http:// fanno passare qualunque altra porcheria scrivo.

Salvare i valori nella form.

Può essere fatto così:


         <input type="text" name="name" value="<?php echo $name;?>">
         
         <textarea name="comment" id="testo" rows="5" cols="40" ><?php echo $comment;?></textarea>
        
         <input type="radio" name="gender"
         <?php if (isset($gender) && $gender=="female") echo "checked";?>
         value="female">Female