Come proteggere il mio codice di autenticazione?

0

Sto lavorando a un progetto PHP in cui ho bisogno di autenticare gli utenti su un portale. Volevo solo avere la tua opinione sul codice, le statistiche del sito mostrano alcuni strani comportamenti con il modulo di login. Ti chiedi se il codice è abbastanza strong.

conn.php

<?php
if(!isset($_GET['login']) && !isset($_GET['pwd']))
{
    header('Location: index.php');
}
else
{
    if(!preg_match('/^[[:alnum:]]+$/', $_GET['login']) or
!preg_match('/^[[:alnum:]]+$/', $_GET['pwd']))
    {
        echo 'Only alphanumeric characters are allowed';
        exit();
    }
    else
    {
        require('config.php');

        $login = $_GET['login'];
        $pwd = $_GET['pwd'];

        $sql = "SELECT * FROM users WHERE user='".mysql_escape_string($login)."'";

        // Check if user exists
        $request_1 = mysql_query($sql) or die ( mysql_error() );

        if(mysql_num_rows($request_1)==0)
        {
            echo 'User does not exist!';
            exit();
        }
        else
        {
            $request_2 = mysql_query($sql." AND pass='".$pwd."'") or die ( mysql_error() );

            if(mysql_num_rows($request_2)==0)
            {
                $result = mysql_fetch_array($request_1, MYSQL_ASSOC);
                $lastconn = explode(' ', $result["dates"]);
                $lastday = explode('-', $lastconn[0]);

                $nbr_trial = $result["nbr_connect"];
                if($lastday[2]==date("d") && $MAX_trial==$nbr_trial)
                {
                    echo 'Too many connection attempts!<br/>';
                    exit();
                }
                else
                {
                    $nbr_trial++;
                    $update = "UPDATE users SET nbr_connect='".$nbr_trial."', dates=NOW()
WHERE id='".$result["id"]."'";
                    mysql_query($update) or die ( mysql_error() );
                    echo 'Incorrect login or password';
                    exit();
                }
            }
            else
            {
                $result = mysql_fetch_array($request_2, MYSQL_ASSOC);
                $nbr_trial = 0;
                $update = "UPDATE users SET nbr_connect='".$nbr_trial."', dates=NOW()
WHERE id='".$result["id"]."'";

                mysql_query($update) or die ( mysql_error() );

                header('Location: portal/index.php');
            }
        }
    }
}
?>

config.php : 

<?php

$DB_serveur = 'localhost';
$DB_utilisateur = 'root';
$DB_motdepasse = '******';
$DB_base = 'siht_portal';

define('_MAX_trial', 3);

?>
    
posta irisgenevill 24.03.2016 - 10:20
fonte

1 risposta

3

Ci sono un paio di cose che vengono in mente. Tuttavia, questo elenco probabilmente non è completo.

  1. Sei sicuro di questa frase if?

    if (! isset ($ _ GET ['login']) &! ampet ($ _ GET ['pwd']))

    Forse dovresti andare su index.php quando login o password non sono impostati (invece di AND).

  2. mysql_escape_string non è necessariamente sicuro, e anche mysql_real_escape_string potrebbe causare problemi come puoi leggere qui: link

    AFAIK si dovrebbe andare con le dichiarazioni preparate: link

  3. In generale, non consiglierei di fornire ulteriori informazioni come assolutamente necessarie. Un potenziale utente malintenzionato potrebbe provare diversi nomi utente fino a quando non ottiene "L'utente non esiste!" - messaggio di errore. Da allora, ha già scoperto il 50% delle credenziali di accesso! Ti consiglio di rispondere "Errore di accesso" o qualcosa di simile, indipendentemente dal fatto che il nome utente o la password non siano corretti.

  4. Ovviamente, la password viene memorizzata nella tabella come testo normale. Questo è un problema, perché se qualcuno ha rubato i dati della tabella (o anche l'intero database), l'utente malintenzionato ha tutte le password. Considera l'hashing per evitare questo problema: link

  5. La maggior parte delle persone ritiene che sia meglio memorizzare le credenziali del database in un file separato: link

  6. Stai utilizzando GET invece di POST, come sottolineato da marstato: l'OP sta leggendo username e passwort da $ _GET. Ciò ostacola quasi interamente SSL e l'uso di caselle di immissione password (type="password" invece di type="text"). Le credenziali verranno visualizzate nei file di registro in molti, molti luoghi a cui realmente non appartengono.

  7. Non stai sfuggendo alla password nella tua query. Chiunque può accedere come chiunque altro, ad es. utente con nome utente "Admin" e password "%" AND ""="restituirebbero dati validi nel risultato della query e passeranno i test di accesso.

risposta data 24.03.2016 - 17:37
fonte

Leggi altre domande sui tag