Mijn login veilig maken

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Jeroen de wilde

Jeroen de wilde

10/08/2018 13:50:22
Quote Anchor link
Hoi,

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)
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
<?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
}
}

?>
 
PHP hulp

PHP hulp

17/10/2018 12:55:05
 
Thomas van den Heuvel

Thomas van den Heuvel

10/08/2018 14:07:35
Quote Anchor link
Haakjes?
(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.
 
- Ariën -
Beheerder

- Ariën -

10/08/2018 14:09:16
Quote Anchor link
Als je mysqli_real_escape_string gebruikt moet je natuurlijk ook systematisch overal mysqli functies in PHP gebruiken.

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 -
 
Willem vp

Willem vp

10/08/2018 14:14:22
Quote Anchor link
> Maar als ik een sql injectie test doe 'OR'1'='1 werkt de login gewoon.

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())
 
Jeroen de wilde

Jeroen de wilde

10/08/2018 16:01:19
Quote Anchor link
Bedankt allemaal voor de hulp en het advies.
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)
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
<?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
}
}

?>
 
- Ariën -
Beheerder

- Ariën -

10/08/2018 16:09:06
Quote Anchor link
Lees even de reactie nog goed door, merendeel heb je niet of fout toegepast.
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 -
 
Thomas van den Heuvel

Thomas van den Heuvel

10/08/2018 16:27:45
Quote Anchor link
Dit wordt ondertussen mijn favoriete aangehaalde passage: 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.
 
Jeroen de wilde

Jeroen de wilde

10/08/2018 17:50:15
Quote Anchor link
Bedankt,

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
 
- Ariën -
Beheerder

- Ariën -

10/08/2018 18:07:55
Quote Anchor link
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.
Gewijzigd op 10/08/2018 18:14:27 door - Ariën -
 
Thomas van den Heuvel

Thomas van den Heuvel

10/08/2018 19:51:59
Quote Anchor link
Bepaalde karakters of bepaalde karakterreeksen kunnen in een bepaalde context (in een HTML-document, een SQL-query, in JavaScript, een XML-document et cetera) een speciale betekenis hebben die de werking van zo'n stuk functionaliteit kan manipuleren. Soms op een zodanige wijze dat de werking een ongewenst of zelfs schadelijk effect heeft. Zo'n inbraak op de werking wordt doorgaans ook wel een injectie genoemd.

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 flansen zetten.
 
Jeroen de wilde

Jeroen de wilde

11/08/2018 15:37:50
Quote Anchor link
Super bedankt voor de hulp en informatie
 



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.