inlogsysteem, veilig?
Ik ben op dit moment bezig met een inlogsysteem voor een webomgeving (PHP, MySQL) waarbij gebruikers worden geauthenticeerd d.m.v. de gebruikersgegevens in Active Directory. Dit wil ik doen dmv de functie ldap_connect(); en ldap_bind(); .
Nu lukt mij dit al aardig, maar ik vraag mij af of ik dit wel veilig genoeg doe met betrekking tot het ingevulde password. Nu doe ik dit als volgt; De gebruiker vult zijn gebruikersnaam en wachtwoord in en met deze maken we verbinding met de LDAP-server. Wanneer de verbinding gelukt is, krijgen we een boolean TRUE terug. dit gaat ook goed. Het probleem is dat de POST-var met het wachtwoord niet versleuteld wordt verzonden van client naar server en ik vraag mij af of dit wel verantwoordelijk is?
Mits ik dit kan versleutelen met MD5 icm SHA1 zou ik graag willen weten hoe dit gedaan kan worden, omdat ik de wachtwoorden niet kan vergelijken...
Dit is mijn script;
Code (php)
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
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
<table class="logintable">
<tr>
<td>Gebruikersnaam</td>
<td><input name="username" type="text" id="username" <?php if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['username'])) { ?> value="<?php echo $_POST['username']; ?>"<?php } ?> /> <span title="De gebruikersnaam is vereist." style="color:red;visibility:block;">*</span></td>
</tr>
<tr>
<td>Wachtwoord</td>
<td><input name="password" type="password" id="password" /> <span title="Wachtwoord is vereist." style="color:red;visibility:block;">*</span></td>
</tr>
<tr>
<td colspan="2"><input type="submit" name="login" value="Aanmelden" id="login" /> <span style="visibility:hidden;">*</span></td>
</tr>
</table>
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (trim($_POST['username']) == "") {
die('Er is geen gebruikersnaam ingevuld!');
}
if (trim($_POST['password']) == "") {
die('Er is geen geldig wachtwoord ingevuld!');
}
// opvangen ingevulde username
$username = strtolower(trim($_POST['username']));
// opvangen ingevuld wachtwoord
$password = $_POST['password'];
// Domeincontroller definieren (UNC-naam of IP)
$server = "webserver-01";
// maak verbinding met domeincontroller
$connect = ldap_connect($server) or die('Server \'webserver-01\' niet beschikbaar!');
// verbinden met de domeincontroller op basis van username en password ingevuld
$bind = ldap_bind($connect,$username."@domain.com",$password) or die('Aanmelding mislukt!');
// Verifieren van verbinding. Indien ok, ga door naar website, anders ga terug naar inlogpagina met foutmelding.
if ($bind == true) {
echo 'Verificatie OK!';
// stel sessie-vars in na goede verificatie
$_SESSION['inlogstatus'] = 1;
$_SESSION['inloguser'] = ucfirst($username);
$_SESSION['inlogtijd'] = date('G:i:s');
$_SESSION['inlogverlooptijd'] = date('G:i:s', mktime(date('G'), date('i')+30, date('s')));
// vernietig var met password
unset($_POST['password']);
// ga naar de index van /db v3
header("Location: index.php?afd=1");
} else { .. }
}
?>
<tr>
<td>Gebruikersnaam</td>
<td><input name="username" type="text" id="username" <?php if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['username'])) { ?> value="<?php echo $_POST['username']; ?>"<?php } ?> /> <span title="De gebruikersnaam is vereist." style="color:red;visibility:block;">*</span></td>
</tr>
<tr>
<td>Wachtwoord</td>
<td><input name="password" type="password" id="password" /> <span title="Wachtwoord is vereist." style="color:red;visibility:block;">*</span></td>
</tr>
<tr>
<td colspan="2"><input type="submit" name="login" value="Aanmelden" id="login" /> <span style="visibility:hidden;">*</span></td>
</tr>
</table>
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (trim($_POST['username']) == "") {
die('Er is geen gebruikersnaam ingevuld!');
}
if (trim($_POST['password']) == "") {
die('Er is geen geldig wachtwoord ingevuld!');
}
// opvangen ingevulde username
$username = strtolower(trim($_POST['username']));
// opvangen ingevuld wachtwoord
$password = $_POST['password'];
// Domeincontroller definieren (UNC-naam of IP)
$server = "webserver-01";
// maak verbinding met domeincontroller
$connect = ldap_connect($server) or die('Server \'webserver-01\' niet beschikbaar!');
// verbinden met de domeincontroller op basis van username en password ingevuld
$bind = ldap_bind($connect,$username."@domain.com",$password) or die('Aanmelding mislukt!');
// Verifieren van verbinding. Indien ok, ga door naar website, anders ga terug naar inlogpagina met foutmelding.
if ($bind == true) {
echo 'Verificatie OK!';
// stel sessie-vars in na goede verificatie
$_SESSION['inlogstatus'] = 1;
$_SESSION['inloguser'] = ucfirst($username);
$_SESSION['inlogtijd'] = date('G:i:s');
$_SESSION['inlogverlooptijd'] = date('G:i:s', mktime(date('G'), date('i')+30, date('s')));
// vernietig var met password
unset($_POST['password']);
// ga naar de index van /db v3
header("Location: index.php?afd=1");
} else { .. }
}
?>
De dingen waar je in ieder geval op moet letten bij registratie:
addslashes/mysql_real_escape_string om je gebruikersnaam EN wachtwoord heen(google effe op SQL injection)
En je wachtwoord versleuten met md5 is gewoon een functie.. md5($_POST['wachtwoord'])
Bij het inloggen kun je dat wachtwoord checken door het ingevulde wachtwoord weer md5($_POST['wachtwoord']) te doen, zodat de md5's overeen komen
Doe het via SSL, dan wordt het altijd gecodeerd.
SSL kost bij de meeste providers een hoop geld...
Code (php)
Je moet even zelf de juiste codevorm vinden want dit zal waarschijnlijk niet werken, dit is wel een manier om de DIE te vervangen.
Daarnaast kan je beter de hele combinatie (username is gelijk aan die in de database, wachtwoord ook gelijk aan die in de database) in een keer kunnen controleren ipv weer te geven of alleen de username of alleen het wachtwoord fout is. Dit kan je ook opvangen door bijvoorbeeld een echo te geven met combinatie niet herkend (bij beide echo's en controle's).
Ook een externe connect kan oplossing bieden, meestal veiliger.
Je kan toch ook gewoon een echo gebruiken en daarna een die uitvoeren? :)
Code onderbreken wordt niet altijd door iedereen gewaardeerd, omdat dit de code-logica volgens sommige puristen ondermijnd. Het is jou keuze of je het zo toepast. Justin noemt een manier die in zijn optiek netter is. Het is maar net wat je afspreek. die() heeft natuurlijk meer nadelen dat dat, maar dat is je eigen keuze. (template/layout parser komt niet meer aan bod bijv.)