• User

    Script Login: è sicuro? Come mostro un errore sotto il form?

    Salve a tutti signori/e,
    vi seguo da un pò di tempo anche se mi sono appena registrato!

    Da un pò di tempo studio a scopo professionale HTML, CSS, PHP e MySQL.
    In questo momento mi trovo ad avere a che fare con il primo lavoro serio.

    Fortunatamente fin quì non ho avuto grossi problemi anzi. Vi spiego meglio:
    l'obiettivo è quello di creare un'area protetta tramite form di login e fin quì tutto bene, vorrei un vostro parere sulla sicurezza dei dati inviati alla query per confrontare user/password con quelli presenti in database.

    config.php
    [php]
    <?php

    // Impostazioni di connessione al Database

    $host = "localhost"; // solitamente LOCALHOST oppure un IP fornito dal servizio di WebHosting
    $username = "root"; // username di acesso al database
    $password = ""; // password di accesso al databse
    $db = "pippo"; // nome database generalmente fornito dal servizio di WebHosting
    $tbl_name = "membri"; // nome tabella contenente dati utenti

    // Funzione di controllo esistenza tabella

    function table_exists($tbl_name) {

    $result = mysql_query('select * from ' . $tbl_name);
    if (!$result) {
    return FALSE;
    }

    else {

    return TRUE;
    }

    // Controllo che il nome database è stato inserito e la tabella selezionata esiste

    if ($db != NULL) { // Verifico che sia stato impostato il nome del database

    $conn = mysql_connect($host, $username, $password) or die ("<b>Impossibile collegarsi al database selezionato:</b><br />" . mysql_error());
    mysql_select_db($db, $conn) or die ("<b>Impossibile selezionare il database impostato:</b> <br />" . mysql_error());

    }
    else { // se la variabile $db non è definita o vi è un errore di battitura mostro un messaggio

     echo "<b>Nome Database</b> non impostato correttamente. Controllare config.php";
     exit; // fermo l'esecuzione del programma
     }
    

    if (table_exists($tbl_name)) { // Verifico che la tabella selezionata esiste e la confermo

    $tbl_name_ok = $tbl_name;

    }
    else { // se la tabella non esiste o vi è un errore di battitura mostro un messaggio

    echo "La <b>Tabella</b> impostata non esiste. Controllare config.php";
    exit; // fermo l'esecuzione del programma

    }

    ?>
    [/php]funzioni.php
    [php]
    <?php

    // fuinzione 'safe': controlla un valore in ingresso rimuovendo gli SLASH e i CARATTERI SPECIALI - Utilizzata per controllare i dati di login inseriti nel form prima di passarli tramite query al database

    function safe($valore_da_controllare){

    if (!get_magic_quotes_gpc()) {
    
    $check1 = addslashes(stripslashes($valore_da_controllare)); // rimuove gli shash pericolosi da $valore_da_controllare
    $check2 = mysql_real_escape_string($check1); // rimuove i caratteri speciali da  $check1
    
    return $check2;
    
    }
    
    else {
    
    return    $valore_da_controllare;
    
    }
    

    }

    ?>
    [/php]checklogin.php [action del form di login]
    [php]
    <?php

    // Richiedo la configurazione dei dati del database e ci colleghiamo ad esso

    require ("config.php");

    // Definisco $myusername e $mypassword con i dati recuperati dal form di login
    $myusername = $_POST['nomeutente'];
    $mypassword = $_POST['pass'];

    // Controlliamo i dati recuperati dal form di login per prevenire attacchi tipo MySQL Injection tramite la funzione safe() in funzioni.php

    include ("funzioni.php");

    $myusername = safe($myusername);
    $mypassword = safe($mypassword);

    // cripto la password ricevuta con la funzione md5()x2 dato che la pass nel database è criptata

    $mypassword = md5(md5($mypassword));

    // interrogo il database alla ricerca di una conbinazione user/pass

    $sql = "SELECT * FROM $tbl_name_ok WHERE user_name='$myusername' and user_pwd='$mypassword'";

    $result = mysql_query($sql);

    // Richiedo a Mysql il numero di record trovati con l'username e la password insieriti nel form di login
    $count = @mysql_num_rows($result);

    // Se i dati inseriti nel form corrispondono a quelli insieriti in database dovremmo avere una singola riga/record
    if ($count == 1){

    // Se è stata trovata una sola riga possiamo registrare la sessione e portare alla pagina protetta principale
    session_start();

    $_SESSION['login_ok'] = TRUE;
    $_SESSION['username'] = "$myusername";

    header("location:privata.php");

    }
    else { // Se non sono stati trovati record i dati inseriti non sono corretti

    echo "Combinazione Username e Password non corretta!";
    }

    ?>
    [/php]codice di controllo sulle pagine protette:
    [php]
    <?php

    session_start();

    $id_sessione = session_id();
    $login_username = @$_SESSION['username'];
    $login_status = @$_SESSION['login_ok'];

    if ($login_status == NULL)
    {
    echo 'Accesso alla pagina richiesta non consentito.';
    exit();
    }

    // controllo che la sessione user esiste

    else { echo "ok! <br />
    Benvenuto $login_username!

    l'id sessione è: $id_sessione <br />";
    ?>

    <a href="destroy.php"> Clicca Quì per distruggere la sessione!!<a/> <br />
    <a href="../index.php"> Clicca Quì per tornare alla homepage!!<a/>
    <?php
    }
    ?>
    [/php]Adesso le domande sono due:

    1. **il tutto è abbastanza sicuro? poco?abbastanza?molto? :bigsmile:

    **2)se volessi che gli errori tipo "Combinazione Username e Password non corretta!" vengano stampati nel modulo del menu di login sotto i form anzichè in una pagina vuota e bianca, come posso fare? so che potrebbe sembrare una domanda stupida, ma nn riesco a venirne a capo!

    Grazie mille, scusate per il poema!
    mCk


  • User

    ehm.. scusate ho scritto qualcosa che non va? 😞


  • User Attivo

    Secondo me la funzione safe() non è tanto safe.
    Io la modificherei cosi:

    
    function safe($valore_da_controllare){
        //solo un mysql_real_escape_string()
        return   mysql_real_escape_string($valore_da_controllare);
    
    }
    ```Non capisco l'utilità di ```
    if (!get_magic_quotes_gpc())
    ``` e di ```
    $check1 = addslashes(stripslashes($valore_da_controllare));
    ```perchè anche se get_magic_quotes_gpc() restituisce true non credo siano sicuri i dati, quindi un bel mysql_real_escape_string() in ongi caso ci vuole.
    
    2)
    Per gestire gli errori usa le sessioni, per es. al posto di questo
    

    else { // Se non sono stati trovati record i dati inseriti non sono corretti

    echo "Combinazione Username e Password non corretta!";
    }

    else { // Se non sono stati trovati record i dati inseriti non sono corretti

    $_SESSION['login_error'] = "Combinazione Username e Password non corretta!";
    }

    if(isset($_SESSION['login_error']))
    echo $_SESSION['login_error'];


  • User

    Intanto ti ringrazio moltissimo per la risposta!

    Riguardo il punto 1) mi hai fatto notare che con la funzione impostata in quella maniera non ho raggiunto esattamente lo scopo che mi ero prefessato.

    Avevo inserito

    [php]if (!get_magic_quotes_gpc())[/php]in modo da rendere la funzione valida e ed applicare addshashes() e stripslashes() a prescindere se il servizio di hosting di default ha impostato i magic_quotes ad OFF oppure ON, però mi rendo conto che come dici tu e il bel mysql_real_escape_string() deve essere applicato in entrambi i casi, poichè i magic quotes non fanno anche la sua funzione.

    quindi che ne pensi se imposterei la funzione safe() in questa maniera?

    [php]
    function safe($valore_da_controllare){

    if (!get_magic_quotes_gpc()) {
    
    $check1 = addslashes(stripslashes($valore_da_controllare)); // rimuove gli shash pericolosi da $valore_da_controllare
    }
    
    else {
    
    $check1 = $valore_da controllare;
    
    }
    
    $check2 = mysql_real_escape_string($check1); // rimuove i caratteri speciali da  $check1
    
    return $check2;
    

    }

    ?>
    [/php]in questo modo, se ciò che ho scritto è giusto [sono le 3 :giggle:], la funzione dovrebbe funzionare in questa maniera:

    - se i magic_quote sono attivati: non è un problema e passo solo il mysql_real_escape_string, se qualche slash è rimasto verrà automaticamente tolto al momento in cui verrà passata la query;

    - se i magic_quote sono disattivati: vengono subito tolti/aggiunti gli slash pericolosi e successivamente anche i caratteri speciali grazie a mysql_real_escape_string

    che ne pensi?? 😄

    riguardo il punto 2)

    dopo una giornata di riflessioni oggi pomeriggio ho usato le sessioni come mi hai consigliato adesso tu! Forse devo imparare ad avere un pò più fiducia in quello che scrivo! 🙂

    Domani posto il codice, magari avrai voglia di darmi un parere anche su quello!

    Grazie ancora!


  • User Attivo

    Ciao,
    si cosi la funzione safe è sciura dato che il valore viene passato in ogni caso da mysql_real_escape_string().

    Posta pure il codice quando finisci, cosi ti do il mio modesto parere :).


  • User

    Volevo porvi una domanda..

    Secondo voi le sessioni bastano a rendere sicuro il Login e le pagine protette o c'è bisogno anche dei Cookie?

    Grazie per le eventuali risposte!