Mijn login veilig maken
Ik heb een login-form gemaakt deze werkt perfect.
Maar als ik een sql injectie test doe 'OR'1'='1 werkt de login gewoon.
als ik dan mysqli_real_escape_string gebruik dan werkt de login niet.
Hopelijk kunnen jullie me helpen.
Alvast dank
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
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
<?php
if (isset($_SESSION['loginId'] )){ // direct doorsturen als men ingelogd is ...
if ($_SESSION['regelment'] == "0") {
header("location: voorwaarden.php");
}else{
header("location: dashboard.php");
}
}else{
if (isset($_POST['login'])){
/************ select ******************/
//echo get_magic_quotes_gpc(); // zo kan je checken of magoc quotes aan of af ligt 0 = off - 1 = on
/*** SECURITY !! zorg dat magical quotes aanstaat in de php ini ***/
$login = htmlentities($_POST['login']);
/*md5 versleuteling, unieke string opp basis van een woord */
$paswoord = md5($_POST['paswoord']);
// Maak een query die login en paswoord zoekt
$query ="SELECT * FROM `leden` where `email` = '".$login ."' OR `login` = '".$login ."' AND `paswoord` = '".$paswoord."'";
// resultaat maken door query uit te voeren met onderstaand commando
$result = mysql_query($query) or trigger_error( mysql_error() );
// controle of login en paswoord correct zijn
if( mysql_num_rows( $result ) == 0 || empty($login) || empty($paswoord)){
$error = "Login en paswoord verkeerd!"; // geen records gevonden / login is leeg of paswoord is leeg ...
}else{
// maak een array met de gegevens
$rij = mysql_fetch_array($result);
// Maal session variabelen die blijven standaard 20 minuten bestaan
$_SESSION['loginId'] = $rij['id'];
$_SESSION['loginNaam'] = $rij['voornaam'];
header("location: dashboard.php"); // stuur door naar de overzicht pagina
}
}
?>
if (isset($_SESSION['loginId'] )){ // direct doorsturen als men ingelogd is ...
if ($_SESSION['regelment'] == "0") {
header("location: voorwaarden.php");
}else{
header("location: dashboard.php");
}
}else{
if (isset($_POST['login'])){
/************ select ******************/
//echo get_magic_quotes_gpc(); // zo kan je checken of magoc quotes aan of af ligt 0 = off - 1 = on
/*** SECURITY !! zorg dat magical quotes aanstaat in de php ini ***/
$login = htmlentities($_POST['login']);
/*md5 versleuteling, unieke string opp basis van een woord */
$paswoord = md5($_POST['paswoord']);
// Maak een query die login en paswoord zoekt
$query ="SELECT * FROM `leden` where `email` = '".$login ."' OR `login` = '".$login ."' AND `paswoord` = '".$paswoord."'";
// resultaat maken door query uit te voeren met onderstaand commando
$result = mysql_query($query) or trigger_error( mysql_error() );
// controle of login en paswoord correct zijn
if( mysql_num_rows( $result ) == 0 || empty($login) || empty($paswoord)){
$error = "Login en paswoord verkeerd!"; // geen records gevonden / login is leeg of paswoord is leeg ...
}else{
// maak een array met de gegevens
$rij = mysql_fetch_array($result);
// Maal session variabelen die blijven standaard 20 minuten bestaan
$_SESSION['loginId'] = $rij['id'];
$_SESSION['loginNaam'] = $rij['voornaam'];
header("location: dashboard.php"); // stuur door naar de overzicht pagina
}
}
?>
(A OR B) AND C
is iets compleet anders dan
A OR (B AND C)
get_magic_quotes() is er allang uit.
htmlentities() helpt niet bij beveiliging in queries - dit is escaping voor de HTML-context, niet voor een SQL-context.
Het makkelijkste is gewoon alle DATA die je invoegt in SQL te voorzien van quotes + een real_escape_string() functie, het een is niet veilig zonder het ander.
Daarbij hoort na een header('Location: ...') eigenlijk altijd een exit;.
En MD5 voor hashing van wachtwoorden is inmiddels ook achterhaald, gebruik password_hash() en password_verify().
Dus, ik weet niet waar je deze ouwe meuk vandaan hebt, maar het wordt waarschijnlijk tijd om wat kennis op te frissen over deze onderwerpen.
Houd ook rekening dat md5() als hashing-algoritme voor je wachtwoorden niet meer veilig is. Gebruik liever bCrypt met password_hash() een een controle met password_verify().
Ook hoort er na een location-header een exit(). Je script moet ook stoppen.
Gewijzigd op 10/08/2018 16:16:18 door - Ariën -
Dan werkt je formulier dus niet perfect. ;-)
Waar/waarop heb je de mysqli_real_escape_string gebruikt? Op $query (fout) of op $login en $password (goed)?
Ander dingetje: je query is sowieso niet goed.
SELECT * FROM leden where email = '$login' OR login = '$login' AND paswoord = '$paswoord'
AND precedeert boven OR, dus eigenlijk staat hier dit:
SELECT * FROM leden where email = '$login' OR (login = '$login' AND paswoord = '$paswoord')
Anders gezegd: als je een geldig email-adres opgeeft, kun je inloggen zonder dat je password wordt gecontroleerd.
Je bedoelt waarschijnlijk:
SELECT * FROM leden where (email = '$login' OR login = '$login') AND paswoord = '$paswoord'
En md5 gebruiken om je password te versleutelen: ík zou het niet durven... (hint: password:hash())
Ik heb nu de onderstaande code
Enkel als ik de $login = htmlentities($_POST['login']); wijzig in $login = mysqli_real_escape_string($_POST['login']);
Dan werkt mijn login niet.
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
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
<?php
if (isset($_SESSION['loginId'] )){ // direct doorsturen als men ingelogd is ...
if ($_SESSION['regelment'] == "0") {
header("location: voorwaarden.php");
}else{
header("location: dashboard.php");
}
}else{
if (isset($_POST['login'])){
/************ select ******************/
$login = mysqli_real_escape_string($_POST['login']);
/*md5 versleuteling, unieke string opp basis van een woord */
$paswoord = hash($_POST['paswoord']);
// Maak een query die login en paswoord zoekt
$query =" SELECT * FROM leden where (email = '$login' OR login = '$login') AND paswoord = '$paswoord'";
// resultaat maken door query uit te voeren met onderstaand commando
$result = mysql_query($query) or trigger_error( mysql_error() );
// controle of login en paswoord correct zijn
if( mysql_num_rows( $result ) == 0 || empty($login) || empty($paswoord)){
$error = "Login en paswoord verkeerd!"; // geen records gevonden / login is leeg of paswoord is leeg ...
}else{
// maak een array met de gegevens
$rij = mysql_fetch_array($result);
// Maal session variabelen die blijven standaard 20 minuten bestaan
$_SESSION['loginId'] = $rij['id'];
$_SESSION['loginNaam'] = $rij['voornaam'];
header("location: dashboard.php"); // stuur door naar de overzicht pagina
}
}
?>
if (isset($_SESSION['loginId'] )){ // direct doorsturen als men ingelogd is ...
if ($_SESSION['regelment'] == "0") {
header("location: voorwaarden.php");
}else{
header("location: dashboard.php");
}
}else{
if (isset($_POST['login'])){
/************ select ******************/
$login = mysqli_real_escape_string($_POST['login']);
/*md5 versleuteling, unieke string opp basis van een woord */
$paswoord = hash($_POST['paswoord']);
// Maak een query die login en paswoord zoekt
$query =" SELECT * FROM leden where (email = '$login' OR login = '$login') AND paswoord = '$paswoord'";
// resultaat maken door query uit te voeren met onderstaand commando
$result = mysql_query($query) or trigger_error( mysql_error() );
// controle of login en paswoord correct zijn
if( mysql_num_rows( $result ) == 0 || empty($login) || empty($paswoord)){
$error = "Login en paswoord verkeerd!"; // geen records gevonden / login is leeg of paswoord is leeg ...
}else{
// maak een array met de gegevens
$rij = mysql_fetch_array($result);
// Maal session variabelen die blijven standaard 20 minuten bestaan
$_SESSION['loginId'] = $rij['id'];
$_SESSION['loginNaam'] = $rij['voornaam'];
header("location: dashboard.php"); // stuur door naar de overzicht pagina
}
}
?>
Zo is hash geen bestaande PHP-functie, en gebruik je nog de verouderde MySQL-functies in plaats van MySQLi.
En nog een aantal dingen hier in dit topic genoemd zijn.
NB: Het is 'wachtwoord' of 'password', maar geen 'paswoord' ;-)
Gewijzigd op 10/08/2018 16:15:08 door - Ariën -
header('Location: ...') transporteert je NIET (meteen) automagisch naar de nieuwe locatie (interne link).
Dit kan serieuze veiligheidslekken introduceren. Daarom is het handiger om hier een functie van te maken die meteen alles regelt, zoals ook in die reactie staat uitgelegd.
Dit wordt ondertussen mijn favoriete aangehaalde passage: Dit kan serieuze veiligheidslekken introduceren. Daarom is het handiger om hier een functie van te maken die meteen alles regelt, zoals ook in die reactie staat uitgelegd.
Ik vervang alles naar mysqli en ik gebruik de functie voor de headers.
Wat zou ik nog moeten toepassen bij $login = htmlentities($_POST['login']);
Nogmaals dank voor de hulp
mysqli_real_escape_string natuurlijk gebruiken. Je wilt niet dat iemand met een SQL-injection je database leegtrekt. Lees wel de manual even door van alle mysqli-functies. Want het is vaak niet enkel een 'i' toevoegen, maar in sommige gevallen moet je verwijzen naar je connectie.
Of je moet de object georiënteerde versie gebruiken, welke ik eigenlijk aanraad. Die kan je makkelijker uitbouwen met eigen functies, als je wilt.
Of je moet de object georiënteerde versie gebruiken, welke ik eigenlijk aanraad. Die kan je makkelijker uitbouwen met eigen functies, als je wilt.
Gewijzigd op 10/08/2018 18:14:27 door - Ariën -
Een van de bekendere hacks in systemen is de SQL-injectie, waarbij de werking van een query zodanig wordt gemanipuleerd dat het effect van de query rampzalige gevolgen kan hebben voor de administratie of veiligheid (of beide) in een systeem. Een query die verantwoordelijk is voor het inloggen van leden tot een systeem dient dus 100% waterdicht te zijn voor dit soort onzin. Anders bestaat de kans dat het beveiligingsmechanisme wat ervoor moet zorgen om ongewenste individuen buiten te houden volledig omzeild wordt. En je query moet natuurlijk van zichzelf goed in elkaar zitten, als dit niet het geval is gaat fatsoenlijke escaping je niet redden.
Gelukkig zijn daar (contextspecifieke) escaping-functies, die tot doel hebben specifieke speciale karakters of -reeksen binnen een specifieke context onschadelijk te maken. Zo is er voor (My)SQL real_escape_string(), en voor HTML bijvoorbeeld htmlspecialchars() (die eigenlijk de voorkeur verdient boven htmlentities()).
Een functie gebruiken voor een context waarvoor deze niet bedoeld is heeft echter geen enkele zin. htmlentities() is dan ook ongeschikt voor gebruik in een query. Hiervoor gebruik je (enkele) quotes in combinatie met real_escape_string(). Het een is niet veilig zonder het ander.
En dan is er nog een bijkomende aangelegenheid: character encoderingen. Alle tekst die je ooit ergens ziet in code, documenten of op het scherm heeft een character encoding. Heel kort door de bocht is dit de vertaling van specifieke bitreeksen (nullen en enen) naar de symbolen (letters en cijfers) die deze representeren in een bepaalde character encoding.
Omdat alles een character encoding heeft, dien je er dus ook voor te zorgen dat deze in de pas lopen. Door al je "tekst" gelijk te schakelen ban je namelijk problemen uit die (waarschijnlijk onbewust) ontstaan door (automatische) vertalingen hiertussen als deze van elkaar zouden afwijken. Zo heb je bijvoorbeeld:
- de character encoding waarmee PHP-, HTML- etc. bestanden worden opgeslagen
- de character encoding die wordt meegegeven in de header() of meta-tags voor je HTML-document
- de character encoding die wordt gebruikt bij het maken van een verbinding met je database (via set_charset())
- de character encoding van de database, de tabellen en wellicht de individuele kolommen
En dit is zeker relevant voor escaping want escaping-functionaliteit is (naast het feit dat deze altijd bedoeld is voor een specifieke context) sterk afhankelijk van de character encoding.
Van al deze onderwerpen dien je wat kaas gegeten te hebben voordat je uberhaupt overweegt om een loginsysteem in elkaar te
Super bedankt voor de hulp en informatie