Hoe de identiteit van de persoon vast te stellen

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Pong Zor

Pong Zor

17/01/2012 13:27:15
Quote Anchor link
Hallo.

Ik worstel al een tijdje met een probleem qua authenticatie

Ik doe het nu als volgt:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
    $actie = $_GET['actie'];
    
    if(isSet($actie) && $actie == 'verifieren'){

        
        if($_SERVER['REQUEST_METHOD'] != 'POST'){
            $error = true;
            $error_no_form = true;
        }
        
        else{
            # Omzetten naar variabelen
            $email = $_POST['email'];
            $wachtwoord = $_POST['wachtwoord'];    
    
            if(empty($email) || empty($wachtwoord)){
                $error = true;
                $error_gebruiker_wachtwoord = true;
            }
    
            else{
                # Database selecteren
                $email = addslashes($email);    
                $wachtwoord = crypt($wachtwoord, '$6$rounds=5909$abcdefghijklmnop$');
                
                # Gegevens uit database ophalen.
                $query = "SELECT * FROM gebruikers WHERE email='" . $email . "' " . "AND wachtwoord='" . $wachtwoord . "'";            
                $resultaat = mysql_query($query, $verbindDatabase) or die("A MySQL error has occurred.<br />Query: " . $query . "<br /> Error: (" . mysql_errno() . ") " . mysql_error());
                $aantalRijen_resultaat = mysql_num_rows($resultaat);     
                $rij = mysql_fetch_assoc($resultaat);    
                
                if($aantalRijen_resultaat == 0){        
                    $error = true;
                    $error_verkeerde_gegevens = true;
                }else{
                    $_SESSION['gebruiker_id'] = $rij['gebruiker_id'];
                    $_SESSION['email'] = $rij['email'];
                    $_SESSION['wachtwoord'] = $rij['wachtwoord'];
                    $_SESSION['login'] = true;
                }

            }
        }

    }


Ik controleer de e-mail en het wachtwoord. Als deze leeg zijn dan foutmelding, zo niet dan crypt ik het wachtwoord, want zo staat deze op opgeslagen. De reden dat ik pas later crypt is omdat anders het wachtwoord veld nooit leeg is en je dus nooit die foutmelding kan krijgen dat je geen pass hebt ingevuld.

Daarna controleer ik aan de hand van de informatie de gebruiker in de database, als daar als resultaat 0 uit komt dan bestaat de gebruiker niet, of de gegevens zijn verkeerd. Anders bestaat de gebruiker wel.

Als de gebruiker wel bestaat gaat het voor mijn gevoel mis, ik sla gebruikers id, email en wachtwoord in een sessie op en doe dan ook nog login sessie true eraan toevoegen.

Nu is het gevaarlijk om een wachtwoord in een sessie te knallen, want mocht de sessie gestolen worden zou je in theorie aan de hand van de hash het wachtwoord kunnen genereren.

Wat ik met die sessie doe is het volgende:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
    $query = "SELECT * FROM gebruikers WHERE email='" . $_SESSION['email'] . "' " . "AND wachtwoord='" . $_SESSION['wachtwoord'] . "' AND gebruiker_id = '" . $_SESSION['gebruiker_id'] . "'";        
    $resultaat = mysql_query($query, $verbindDatabase) or die("A MySQL error has occurred.<br />Query: " . $query . "<br /> Error: (" . mysql_errno() . ") " . mysql_error());    
    $rij = mysql_fetch_assoc($resultaat);


Vervolgens bestaat $rij['gebruiker_id'] dus want je bent het hele inlog proces doorlopen

Nu doe ik op elke "beveiligde" pagina het volgende

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
    if(isSet($_SESSION['login']) && isSet($rij['gebruiker_id'])){


Maar ik twijfel dus aan de veiligheid. $_SESSION['login'] kan je handmatig op true zetten, dus deze controle slaat nergens op, dan kijk ik of de gebruiker bestaat, maar deze informatie zou je ook uit de sessie kunnen halen dus ik ben bang dat mijn beveiliging helemaal nergens op slaat.

Heeft iemand tips hoe het beter kan?
 
PHP hulp

PHP hulp

28/03/2024 10:01:30
 
Kris Peeters

Kris Peeters

17/01/2012 13:42:50
Quote Anchor link
Je moet anders redeneren.

Je paswoord sla je sowieso niet op!
Je hebt dat paswoord enkel nodig wanneer de gebruiker inlogt; dus wanneer $_POST['wachtwoord'] actief is.

Aan de hand van $_POST['email'] en $_POST['wachtwoord'] selecteer je een gebruiker uit de lijst.
Indien die gevonden wordt, kan je $_SESSION['gebruiker_id'] zetten.

Sessions worden bijgehouden op de sever. Eens $_SESSION['gebruiker_id'] een waarde heeft, kan je er van uit gaan dat de gebruiker ingelogd is.


Aan de hand van $_SESSION['gebruiker_id'] kan je telkens (bij elke muisklik van de gebruiker) de juiste user selecteren. Dat wachtwoord heb je niet meer nodig.

Dit is een basis. Daarna zijn er nog extra beveiligingsmaatregelen mogelijk. controleren op IP, login tijd opslaan, ... maar eerst de basis
Gewijzigd op 17/01/2012 13:44:43 door Kris Peeters
 
Pong Zor

Pong Zor

17/01/2012 13:45:31
Quote Anchor link
Oke Kris, maar stel $_SESSION['gebruiker_id'] = 1. En ik maak ook een $_SESSION['gebruiker_id'] = 1 aan, dan ben ik toch die gebruiker dan? Zonder ook maar ingelogd of iets te zijn?
 
Jelle -

Jelle -

17/01/2012 13:51:55
Quote Anchor link
Leg mij eens uit hoe jij als gebruiker $_SESSION['gebruiker_id'] veranderd :)

Volgens mij verwar jij sessions met cookies.
 
Pong Zor

Pong Zor

17/01/2012 13:56:27
Quote Anchor link
Ik weet niet precies hoe je het doet, maar er bestaat toch iets zoals session hijacking? Daarmee zou je dat toch kunnen doen dan?
 
Jelle -

Jelle -

17/01/2012 14:09:49
Quote Anchor link
Dan steel je de cookie waarin de sessionid in staat, ga er eerst maar eens wat over lezen :)
 
Pong Zor

Pong Zor

17/01/2012 14:16:25
Quote Anchor link
Hmm oke,

Ik denk dat ik het zo aanpak dan, ik laat een willekeurig getal genereren na het inloggen, deze hash ik en deze sla ik op in de database.

Vervolgens aan de hand van $_SESSION['gebruiker_id'] en $_SESSION['hash'] laat ik de gebruiker autoriseren, lijkt mij wel voldoende dan toch?

Heel eerlijk van session hijacking heb ik nog niet zoveel kaas gelezen, maar dat lijkt idd via cookies te gaan, die gebruik ik sowieso niet.
 
Jelle -

Jelle -

17/01/2012 14:21:09
Quote Anchor link
Jij misschien niet, maar de browser moet toch echt wel een sessionid aan de server leveren om te zeggen "hé, dit ben ik!". En meestal wordt dit id in een cookie opgeslagen.
 
Pong Zor

Pong Zor

17/01/2012 14:22:22
Quote Anchor link
Ja oke, maar deze session_id gebruik ik verder niet, dus dan kunnen ze die wel stelen, maar kunnen ze er niks mee toch?
 
Jelle -

Jelle -

17/01/2012 14:28:31
Quote Anchor link
Nee je begrijp het verkeerd, ik zal het proberen wat duidelijk te maken.

Jij komt op een site waar sessies worden gebruikt. Als je nog geen sessie hebt gaat ie er eentje aanmaken. Dat sessie krijgt een "random" id, die krijgt de browser te horen. Elke keer dat de browser vervolgens naar een pagina van die site gaat waar sessies gebruikt worden, moet hij aangeven wie hij is (sessionid).

Kijk maar eens bij de cookies van je browser van verschillende sites (bijvoorbeeld van phphulp).
 
Pong Zor

Pong Zor

17/01/2012 14:42:20
Quote Anchor link
Hmm oke even iets anders, is het op deze manier zo veilig dan?

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
    if(!isSet($_SESSION)){
        session_start();
        session_regenerate_id(true);
    }  


Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
    if(isSet($actie) && $actie == 'verifieren'){

        
        if($_SERVER['REQUEST_METHOD'] != 'POST'){
            $error = true;
            $error_no_form = true;
        }
        
        else{
            # Omzetten naar variabelen
            $email = addslashes($_POST['email']);
            $wachtwoord = $_POST['wachtwoord'];    
    
            if(empty($email) || empty($wachtwoord)){
                $error = true;
                $error_gebruiker_wachtwoord = true;
            }
    
            else{
                # Database selecteren
                $wachtwoord = crypt($wachtwoord, '$6$rounds=5909$wootsaltforthesecretpassword$');
                
                # Gegevens uit database ophalen.
                $query = "SELECT * FROM gebruikers WHERE email='" . $email . "' " . "AND wachtwoord='" . $wachtwoord . "'";            
                $resultaat = mysql_query($query, $verbindDatabase) or die("A MySQL error has occurred.<br />Query: " . $query . "<br /> Error: (" . mysql_errno() . ") " . mysql_error());
                $aantalRijen_resultaat = mysql_num_rows($resultaat);     
                $rij = mysql_fetch_assoc($resultaat);    
                
                if($aantalRijen_resultaat == 0){        
                    $error = true;
                    $error_verkeerde_gegevens = true;
                }else{
                    
                    $hash = crypt(microtime(), '$6$rounds=5909$supersafehashsalt$');
                    
                    $query_update_sorteervolgorde = sprintf("UPDATE gebruikers SET secret_hash='%s' WHERE gebruiker_id='%s'",
                        mysql_real_escape_string($hash),
                        mysql_real_escape_string($rij['gebruiker_id'])
                    );
                    mysql_query($query_update_sorteervolgorde, $verbindDatabase) or die("A MySQL error has occurred.<br />Query: " . $query_update_sorteervolgorde . "<br /> Error: (" . mysql_errno() . ") " . mysql_error());        
                
                    $_SESSION['gebruiker_id'] = $rij['gebruiker_id'];
                    $_SESSION['hash'] = $hash;

                }

            }
        }

    }


Vervolgens doe ik dan dit:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
    if(isSet($_SESSION['gebruiker_id']) && isSet($_SESSION['hash'])){
        $query = "SELECT * FROM gebruikers WHERE gebruiker_id = '" . $_SESSION['gebruiker_id'] . "' AND secret_hash='" . $_SESSION['hash'] . "'";
        $resultaat = mysql_query($query, $verbindDatabase) or die("A MySQL error has occurred.<br />Query: " . $query . "<br /> Error: (" . mysql_errno() . ") " . mysql_error());    
        $rij = mysql_fetch_assoc($resultaat);    
    }


En uiteindelijk op elke pagina dit:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
if(isSet($rij['gebruiker_id'])){
echo 'toon pagina';
}else{
echo 'toon inlog';
}
Gewijzigd op 17/01/2012 14:43:03 door Pong Zor
 
- SanThe -

- SanThe -

17/01/2012 16:34:52
Quote Anchor link
Script is lek.

Dit: $email = addslashes($email); is geen beveiliging.
Gebruik mysql_real_escape_string().
 
Pong Zor

Pong Zor

17/01/2012 16:40:28
Quote Anchor link
Is dat het enige?
 
- SanThe -

- SanThe -

17/01/2012 16:50:48
Quote Anchor link
Ik zag addslashes() staan, verder niet echt gekeken.
 
Pong Zor

Pong Zor

17/01/2012 17:01:28
Quote Anchor link
Ja klopt, het is beetje samenvoegen van oude code, toen ik nog helemaal noob was in PHP met nieuwe code. Voor de rest vang ik al mijn queries af met escapes.
 
Erwin H

Erwin H

17/01/2012 18:54:51
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
<?php
            $email
= addslashes($_POST['email']);
            $wachtwoord = $_POST['wachtwoord'];    
    
            if(empty($email) || empty($wachtwoord)){
?>

Dit is verkeerd om checken. Eerst gebruik je de $_POST variabelen om daarna de $email en $wachtwoord te gaan controleren of ze wel een waarde hebben. Als die check echt nodig is omdat er geen waarde is, dan ligt je script al met de pootjes omhoog omdat de $_POST variabelen niet bestonden.

Check dus of de $_POST['email'] en $_POST['wachtwoord'] wel bestaan (met isset()) en controleer daarna wat de inhoud is van die $_POST waardes (of zo je wilt van $email en $wachtwoord.

Overigens ben ik persoonlijk dan ook geen fan van gewoon mysql_real_escape_string klakkeloos te gebruiken. Wat mij betreft is het beter om echt de inhoud te controleren, zodat als er een poging is om bijvoorbeeld script of sql code te injecteren dan kan je dat ook opmerkingen en er iets mee doen (loggen, aangifte doen, ip adressen blokkeren, users blokkeren etc etc).
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.