Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

Veilig gebruik sessies (Inlogscript)

Pagina: 1
Acties:
  • 435 views sinds 30-01-2008

  • annuh
  • Registratie: Februari 2006
  • Laatst online: 30-11 20:56
Beste tweakers,
Ik ben bezig met een (eenvoudig) inlogscript. Nu heb ik hierover al diverse tutorials gelezen en diverse scripts. Maar op bijna alle scripts had iedereen wel wat aan te merken op de veiligheid.
Nu was mijn vraag: Hoe maak ik mijn inlogscript (mbv sessies) echt veilig?
Ik ga geen site zoals tweakers.net maken dus het hoeft allemaal ook niet heel erg overdreven natuurlijk!
Ik zat zelf eerst te denken aan het volgende:
User logt in -> Als er combinatie username/password dan goed is maakt het script een sessie aan voor:
- Username
- Controlecode (word dit ook niet een hash genoemd?)
De controlecode word ook een database ‘logins’ opgeslagen.
Op de beveiligde pagina’s word dan gekeken of de combinatie username/controlecode nog klopt. Hier zou ik evt. nog het IP kunnen controleren maar dit lijkt me niet echt makkelijk voor mensen met een dynamisch IP.
Dit is allemaal erg makkelijk (en dat moet ook want ik nog een beginneling :P)
Op internet vond ik de volgende manieren voor zo’n controlecode / unieke login.
Welke vinden jullie de beste? Of hebben jullie nog tips, ik hoor het graag!
code:
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
  if(mysql_num_rows($result)>0){
        while(list($led_id)=mysql_fetch_row($result)){ //id van de gebruiker uit de database halen
            $sessie_id=md5(session_id()); //coderen van sessie id in variable
            $tijd=time(); //tijd in variable zetten
            $ip=$_SERVER['REMOTE_ADDR']; //ip van bezoeker in variable zetten
            
            //unieke string (hash) genereren, do-while gebruiken omdat string minstens 1 keer gegenereerd moet worden indien deze al voor komt in database nieuwe string genereren
            do{
                $array = array ("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "v", "x", "y", "z", 1, 2, 3, 4, 5, 6, 7, 8, 9, 0);
                for($getal=0; $getal<32; $getal++){
                    $waarde=$array[rand(0,33)];
                    $nr=rand(0,1); //getal genereren als getal 1 is teken als hoofdletter zetten
                    if ($nr==1){
                        $waarde=strtoupper($waarde);
                    }
                    $hash .=$waarde;
                }
                $hash=md5($hash);
                
                //alle records ophalen uit database waarvan de hash gelijk is aan de gegenereerde hash
                $query="select hash from b1_sessies WHERE hash='$hash'";
                $result=mysql_query($query)or die (mysql_error());
            }while(mysql_num_rows($result)>0);
            
            //gegevens in sessie zetten
            session_register("hash");            
            session_register("led_id");    
            
            //gegevens in sessie tabel zetten
            $query="INSERT INTO b1_sessies (sessie_id, hash, led_id, tijd_start, led_ip, sessie_naam, sessie_aan_ip) VALUES ('".$sessie_id."','".$hash."','".$led_id."','".$tijd."','".$ip."','".$sessie_naam."','".$sessie_vergrendelen."')";
            mysql_query($query) or die(mysql_error());
        }
        header("location:beveiligd.php");
        exit();
    }else{
        die("<h2>Het inloggen kon niet worden voltooid.</h2>U gaf een foute combinatie van gebruikersnaam en wachtwoord op. <p />Klik ".'<a href="inloggen.php">hier</a>'." om terug te gaan naar het inlog formulier.");
    }


code:
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<?php 

session_start(); 

// Databaseverbinding maken 
@mysql_connect( 'localhost', '...', '...' ) or trigger_error( mysql_error() ); 
@mysql_select_db( '...' ) or trigger_error( mysql_error() ); 

function genereer_string( $lengte ) 
{ 
  srand( ( (double) microtime() ) * 1000000 ); 
  $string = ''; 

  // De parser doet irri met zoveel tekens zonder spaties achter elkaar, dus verdeel ik dit ff over meerdere regels 
  $tekens = 'abcdefghijklmnopqrstuvwxyz'; 
  $tekens .= 'ABCDEFGHIJKLMNOPQRSTUWXYZ'; 
  $tekens .= '01234567890123456789'; 

  for( $i = 0; $i < $lengte; $i++ ) 
  { 
    $string .= $tekens{ rand( 0, ( strlen( $tekens ) - 1 ) ) }; 
  } 

  return $string; 
} 

// Is het formulier gesubmit en staat er een challenge in de sessie ? 
if( isset( $_POST['username'], $_POST['response'], $_SESSION['challenge'] ) ) 
{ 
  $query = "SELECT * FROM tabel WHERE username = '" . $_POST['username'] . "' LIMIT 0,1"; 
  $result = mysql_query( $query ) or trigger_error( mysql_error() ); 
  if( mysql_num_rows( $result ) == 0 ) 
  { 
    echo 'Ongeldige gebruikersnaam en/of wachtwoord'; 
  } 
  else 
  { 
    $rij = mysql_fetch_assoc( $result ); 

    // Response genereren en vergelijken met wat er opgestuurd is 
    if( sha1( $rij['password'] . ':' . $_SESSION['challenge'] ) != $_POST['response'] ) 
    { 
      // Exact dezelfde melding tonen als wanneer de gebruikersnaam niet in de tabel gevonden kon worden. 
      // Hier een andere melding tonen zou de hacker alleen maar inzicht geven over in hoeverre zijn hackpogingen werken. 
      echo 'Ongeldige gebruikersnaam en/of wachtwoord'; 
    } 
    else 
    { 
      // Gebruiker succesvol ingelogd, gegevens opslaan in sessie enzo ... 
      echo 'Yay ! Succesvol ingelogd !'; 
    } 
  } 
} 

// Elke keer dat de pagina aangevraagd is, of er nou een postback gedaan is of niet, de challenge opnieuw genereren ! 
$challenge = genereer_string( 255 ); 
$_SESSION['challenge'] = $challenge; 
?> 

<script type="text/javascript" src="sha1.js"></script> 

<script type="text/javascript"> 
<!-- 
function createResponse() 
{ 
  document.getElementById( 'response' ).value = hex_sha1( hex_sha1( document.getElementById( 'password' ).value ) + ":" + document.getElementById( 'challenge' ).value ); 
  document.getElementById( 'password' ).value = ""; 
  document.getElementById( 'challenge' ).value = ""; 
  return true; 
} 
//--> 
</script> 

<form action="login.php" method="post" onsubmit="return createResponse();"> 
  <div> 
    Username: <input type="text" name="username"> 
    Wachtwoord: <input type="password" id="password"> 
    <input type="hidden" id="challenge" value="<?php echo $challenge; ?>"> 
    <input type="hidden" name="response" id="response" value=""> 
    <input type="submit" value="Log in !"> 
  </div> 
</form>


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?
    // start de sessie
    session_start();

    // ip check en overige dingen..

    $sessdata = $_SESSION;
    unset($sessdata[&#8216;hash&#8217;]);

    sessdata_str = serialize($sessdata);
    $md5hash = md5($sessdata_str);

    // controleren van de hash
    if ($_SESSION[&#8216;hash&#8217;] == $md5hash)
    {
        // hash komt overeen! Sessie is geldig!!
    }
?>


Wat gebeurd er eigenlijk in de volgende regel?
code:
1
$sessie_id=md5(session_id()); //coderen van sessie id in

Er is nog helemaal geen sessie aangemaakt? Of word hier de ‘unieke code’ van de desbetreffende sessie bedoeld?
En wat doet de volgende regel eigenlijk?
code:
1
$md5hash = md5($sessdata_str);
Ik kan weinig vinden over 'serializen'.

Als ik het op een van de bovenstaande manieren doen, zou het dan veilig genoeg zijn?
Alvast bedankt!

EDIT: Ik ga geen hele codes uit andere script overnemen, het gaat hier puur om welke manier veilig (het veiligst is)

[ Voor 25% gewijzigd door annuh op 26-07-2007 17:49 ]


  • japaveh
  • Registratie: Maart 2003
  • Laatst online: 12:27

japaveh

Jield BV

Persoonlijk gebruik ik de manier die hier door crisp wordt uitgelegd: wellicht kun je ook die methode volgen crisp in "[PHP] BeveiligingsTips nodig"

Solo Database: Online electronic logbook and database system for research applications


  • N3oC
  • Registratie: Juni 2006
  • Laatst online: 27-11 15:32
Je kan ook voor het inloggen een capcha maken (plaatje met tekens) om te controlleren of het geen hackattempt is. Dit maakt het inloggen ook veiliger. Ook kan je HTTPS gebruiken om je site op te draaien.

https://www.linkedin.com/in/coenversluis || http://www.judovianen.nl


  • Cartman!
  • Registratie: April 2000
  • Niet online
N3oC schreef op donderdag 26 juli 2007 @ 19:30:
Je kan ook voor het inloggen een capcha maken (plaatje met tekens) om te controlleren of het geen hackattempt is. Dit maakt het inloggen ook veiliger. Ook kan je HTTPS gebruiken om je site op te draaien.
https is alleen om te zorgen dat je niet gesnift kunt worden. Het inloggen zelf zul je alsnog gewoon moeten afhandelen.

Gebruik de methode van crisp die in t genoemde topic hierboven te vinden is. Ik heb een systeem wat ongveer gelijk is daaraan en het werkt erg prettig en is veilig. Wachwoord in de database sla ik (gehashed met SHA256) op met een salt zodat je met de usertabel zelf ook niks meer kan mocht je die op een of andee manier bemachtigd hebben. Voordeel van challenge/response is dat nooit, zelfs niet tijdens t registreen, je wachwood over de lijn hoeft te gaan :)

  • Depress
  • Registratie: Mei 2005
  • Laatst online: 24-11 21:01
Daarbij kost het flink wat duiten om een SSL certificaat aan te schaffen voor je site.

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

mja, je kan gewoon een self-signed certificaat maken als je niet echt iets groots gaat maken... kost 0E, en je hebt wel de MOGELIJKHEID tot echte veiligheid

-niks-


  • annuh
  • Registratie: Februari 2006
  • Laatst online: 30-11 20:56
(Sorry voor deze late reply maar ik was op vakantie enzo maar ik hoop dat ik nog wat antwoorden uit jullie kan krijgen :P )

SSL vind ik een beetje overdreven, het kan toch ook (redelijk) veilig zijn zonder dit?

Ik zat te denken aan het voldende systeem (het is nog een beetje schematisch hoor!)

Als de user inlogt:
De volgende sessions worden aangemaakt:
code:
1
2
3
$_SESSION['login'] = 1 (of TRUE);
$_SESSION['username'] = $_POST['username'];
$_SESSION['session_id'] = md5(rand(0,99999));


In de database word(en) de volgend(e) veld(en) geupdate:
session_id
(en evt. cookie_ID)
(en evt. tijd van de laatste login)

Alk de user zijn login wil onthouden mbv een cookie word de volgende cookie gezet:

username (ook md5? Of zou dat niet nodig zijn?)
cookie_id =md5(rand(0,99999)) + md5($IP)

Op de beveiligde pagina word dus gekeken naar:
of de session['login'] is gezet, als dat zo is word gekeken of de session['session_id'] hetzelfde is als
die uit de database
als dit niet zo is, word er de cookie nog gecontroleerd: als cookie['cookie_id'] hetzelfde is als die uit de database is de user ook ingelogd.
Bij al het andere: niet ingelogd

Kunnen jullie op en aanmerkingen geven op dit? Wat is overbodig en wat moet er verbeterd veranderd worden?
De echt phpcode hier omheen is niet zo moeilijk, het gaat vooral om het idee erachter.
Alvast bedankt!

  • iH8
  • Registratie: December 2001
  • Laatst online: 17-06-2024

iH8

er is in de tussentijd een topic bijgekomen waarin volgens mij al je vragen beantwoord worden:

[PHP] optimale beveiliging beheerfunctie

Aunt bunny is coming to get me!


  • annuh
  • Registratie: Februari 2006
  • Laatst online: 30-11 20:56
Sorry maar ik kan er geen antwoorden op mijn vragen tussenvinden, wel enkele goede tips!
Maar niet hoe ik mijn ' script' kan verbeteren/aanpassen.

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 30-11 15:10

Creepy

Tactical Espionage Splatterer

Jouw script? No offence maar je geeft zelf al aan dat je scripts op internet hebt gevonden. Er zijn echt al een hoop topics over inloggen, beveiliging e.d. voorbij gekomen en ook op google is er het 1 en ander te vinden maar daar lijkt je niks mee gedaan te hebben behalve het kopieren en plakken van code in je startpost zonder verder enige uitleg of uitweiding van die code. Ook de post over het stukje van Crisp (crisp in "[PHP] BeveiligingsTips nodig") lijk je totaal te negeren en hij geeft daar notabene een compleet stappenplan.

Ik snap dat je wilt discussieren over hoe je inloggen e.d. zo veilig mogelijk kan maken maar daar is het hier echt al vaker over gegaan. Lees aub eerst er eens wat meer over door want een hoop vragen die je nu stelt worden daar direct in benantwoord.

Als je wilt weten of je eigen idee echt veilig is zul je meer moeten doen dan het script of het idee neerzetten en vervolgens vragen "nog opmerkingen?". Je zult het op z'n minste moeten onderbouwen wat je hebt gedaan en waarom. Het waarom laat je nu totaal achterwege. Dat laat ons zien dat je er daadwerkelijk zelf mee bezig bent geweest en het levert voor jou alleen maar beter commentaar op omdat wij zouden moeten begrijpen waarom je bepaalde dingen hebt gedaan.

Via e-mail kreeg ik nog het volgende (en geheel terechte) commentaar:
Omdat zijn regel code "$_SESSION['session_id'] = md5(rand(0,99999));" in mijn opzicht echt onveilig is (slechts 100.000 opties) en kans op 2x dezelfde id!

[ Voor 29% gewijzigd door Creepy op 22-08-2007 17:03 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney

Pagina: 1

Dit topic is gesloten.