Beschermen tegen injections
Kunnen jullie mij helpen mijn login systeem zo veilig mogelijk te maken? Hieronder staan mijn codes voor het login script. Alvast bedankt!
index.php
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
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
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
<?php
session_start(); // Start de session \\
// IMPORTEER ALLE BESTANDEN \\
REQUIRE_ONCE 'paneel/include/config.php';
REQUIRE_ONCE 'paneel/include/functions.php';
REQUIRE_ONCE 'paneel/include/login_script.php';
// ACTIVEER DE FUNCTIE 'LOGGED_IN' \\
if(logged_in()) {
header('Location: /dashboard'); // Hier wordt je doorgelinkt naar '/dashboard' als je bent ingelogd \\
die(); // Als je bent ingelogd, volgt de volgende code niet \\
}
// ONDERHOUD INSTELLINGEN \\
$currentLocation = "index"; // PAS DE LOCATIE NIET AAN \\
include 'lib/classes/site.status.php';
?>
<!DOCTYPE html>
<html>
<head>
<script>
<?php echo $disable_form;?>
</script>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=1,initial-scale=1,user-scalable=1" />
<title>
Inloggen - <?php echo $_CONFIG['bedrijf']; ?>
</title>
<link rel="shortcut icon" type="image/gif" href="<?php echo $_CONFIG['bedrijf_logo']; ?>" />
<link rel="stylesheet" type="text/css" href="paneel/style/css/index.css" />
<link href="http://fonts.googleapis.com/css?family=Lato:100italic,100,300italic,300,400italic,400,700italic,700,900italic,900" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="paneel/style/bootstrap/css/bootstrap.min.css" />
</head>
<body>
<section class="container">
<section class="login-form">
<section>
<p style="margin-bottom: -7px; margin-top: -15px; color: black; font-size: 18pt; font-weight: bold;"><?php echo $_CONFIG['bedrijf']; ?></p>
</section>
<div class="panel panel-default">
<div class="panel-body">
<form method="post" id="disable" action="" role="login">
<div class="form-group">
<p style="text-align: center;">Inloggen, geen account? <a class="disable" href='/registreer'>Maak er n!</a></p>
<p style="text-align: center; color: red;"><?php echo $error; ?></p>
<label>Gebruikersnaam</label>
<input autofocus title="Maximaal 50 tekens." type="text" name="gebruikersnaam" maxlength="50" required class="form-control" />
</div>
<div class="form-group">
<label>Wachtwoord</label>
<input title="Maximaal 100 tekens." type="password" name="wachtwoord" maxlength="100" required class="form-control" />
</div>
<input type="checkbox" name="onthoud" value="1" /> Onthoud mijn gegevens.
<button type="submit" name="inloggen" class="btn btn-primary btn-block">Inloggen</button>
</form>
</div>
<div class="panel-footer">
<a href="#">Wachtwoord vergeten?</a>
</div>
</div>
<section>
<a href="<?php $_SERVER["REQUEST_URI"]; ?>">Copyright © <?php echo date("Y"); echo ' <b>'; echo $_CONFIG['bedrijf']; echo '</b>'; ?></a>
</section>
</section>
</section>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="paneel/style/bootstrap/js/bootstrap.min.js"></script>
</body>
session_start(); // Start de session \\
// IMPORTEER ALLE BESTANDEN \\
REQUIRE_ONCE 'paneel/include/config.php';
REQUIRE_ONCE 'paneel/include/functions.php';
REQUIRE_ONCE 'paneel/include/login_script.php';
// ACTIVEER DE FUNCTIE 'LOGGED_IN' \\
if(logged_in()) {
header('Location: /dashboard'); // Hier wordt je doorgelinkt naar '/dashboard' als je bent ingelogd \\
die(); // Als je bent ingelogd, volgt de volgende code niet \\
}
// ONDERHOUD INSTELLINGEN \\
$currentLocation = "index"; // PAS DE LOCATIE NIET AAN \\
include 'lib/classes/site.status.php';
?>
<!DOCTYPE html>
<html>
<head>
<script>
<?php echo $disable_form;?>
</script>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=1,initial-scale=1,user-scalable=1" />
<title>
Inloggen - <?php echo $_CONFIG['bedrijf']; ?>
</title>
<link rel="shortcut icon" type="image/gif" href="<?php echo $_CONFIG['bedrijf_logo']; ?>" />
<link rel="stylesheet" type="text/css" href="paneel/style/css/index.css" />
<link href="http://fonts.googleapis.com/css?family=Lato:100italic,100,300italic,300,400italic,400,700italic,700,900italic,900" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="paneel/style/bootstrap/css/bootstrap.min.css" />
</head>
<body>
<section class="container">
<section class="login-form">
<section>
<p style="margin-bottom: -7px; margin-top: -15px; color: black; font-size: 18pt; font-weight: bold;"><?php echo $_CONFIG['bedrijf']; ?></p>
</section>
<div class="panel panel-default">
<div class="panel-body">
<form method="post" id="disable" action="" role="login">
<div class="form-group">
<p style="text-align: center;">Inloggen, geen account? <a class="disable" href='/registreer'>Maak er n!</a></p>
<p style="text-align: center; color: red;"><?php echo $error; ?></p>
<label>Gebruikersnaam</label>
<input autofocus title="Maximaal 50 tekens." type="text" name="gebruikersnaam" maxlength="50" required class="form-control" />
</div>
<div class="form-group">
<label>Wachtwoord</label>
<input title="Maximaal 100 tekens." type="password" name="wachtwoord" maxlength="100" required class="form-control" />
</div>
<input type="checkbox" name="onthoud" value="1" /> Onthoud mijn gegevens.
<button type="submit" name="inloggen" class="btn btn-primary btn-block">Inloggen</button>
</form>
</div>
<div class="panel-footer">
<a href="#">Wachtwoord vergeten?</a>
</div>
</div>
<section>
<a href="<?php $_SERVER["REQUEST_URI"]; ?>">Copyright © <?php echo date("Y"); echo ' <b>'; echo $_CONFIG['bedrijf']; echo '</b>'; ?></a>
</section>
</section>
</section>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="paneel/style/bootstrap/js/bootstrap.min.js"></script>
</body>
config.php
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
error_reporting(0);
// DE DATABASE INFORMATIE \\
$setting = parse_ini_file('datafile.ini');
$con = new mysqli($setting['db_host'], $setting['db_user'], $setting['db_pass'], $setting['db_name']);
// CONTROLEER DE VERBINDING \\
if ($con->connect_error) {
die('<title>Niet gelukt om te verbinden met MySQL</title>Verbinings fout (' . $con->connect_errno . ') ' . $con->connect_error); // DE ERROR ALS ER EEN FOUT IN DE VERBINDING IS \\
}
// SERVER INSTELLINGEN \\
$_SERVER['admin'] = $setting['admin'];
$_SERVER['admin_ip'] = $setting['admin_ip'];
// CONFIG INSTELLINGEN \\
$result = $con->query("SELECT * FROM `instellingen`")->fetch_array(); // SELECTEER ALLES VAN INSTELLINGEN \\
$_CONFIG['bedrijf'] = ucfirst($result['bedrijf']); // SELECTEER DE BEDRIJFSNAAM \\
$_CONFIG['bedrijf_logo'] = $result['bedrijf_logo']; // SELECTEER HET BEDRIJFS LOGO \\
?>
error_reporting(0);
// DE DATABASE INFORMATIE \\
$setting = parse_ini_file('datafile.ini');
$con = new mysqli($setting['db_host'], $setting['db_user'], $setting['db_pass'], $setting['db_name']);
// CONTROLEER DE VERBINDING \\
if ($con->connect_error) {
die('<title>Niet gelukt om te verbinden met MySQL</title>Verbinings fout (' . $con->connect_errno . ') ' . $con->connect_error); // DE ERROR ALS ER EEN FOUT IN DE VERBINDING IS \\
}
// SERVER INSTELLINGEN \\
$_SERVER['admin'] = $setting['admin'];
$_SERVER['admin_ip'] = $setting['admin_ip'];
// CONFIG INSTELLINGEN \\
$result = $con->query("SELECT * FROM `instellingen`")->fetch_array(); // SELECTEER ALLES VAN INSTELLINGEN \\
$_CONFIG['bedrijf'] = ucfirst($result['bedrijf']); // SELECTEER DE BEDRIJFSNAAM \\
$_CONFIG['bedrijf_logo'] = $result['bedrijf_logo']; // SELECTEER HET BEDRIJFS LOGO \\
?>
login_script.php
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
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
<?php
if(isset($_POST['inloggen'])){
// DEFINITEER $GEBRUIKERSNAAM EN $WACHTWOORD \\
$gebruikersnaam = $_POST['gebruikersnaam'];
$wachtwoord = $_POST['wachtwoord'];
// BESCHERM DE GEGEVENS \\
$gebruikersnaam = $con->real_escape_string($gebruikersnaam);
$wachtwoord = md5($wachtwoord);
// LOGIN SCRIPT \\
$result = $con->query("SELECT * FROM `leden` WHERE `gebruikersnaam`='$gebruikersnaam'")->fetch_array(); // SELECTEER ALLE DATA VAN DE GEBRUIKERSNAAM \\
if (( $gebruikersnaam ) == ( $result['gebruikersnaam'] )){
if (( $wachtwoord ) == ( $result['wachtwoord'] )){
$id = $con->query("SELECT `id` FROM `leden` WHERE `gebruikersnaam`='$gebruikersnaam'")->fetch_array();
$_SESSION['id'] = $id['id'];
header('Location: /dashboard');
}
else{
$error = "Er is een fout wachtwoord ingevoerd voor de gebruiker '$gebruikersnaam'.";
header('Refresh: 2; Url=/');
}
}
else{
$error = "De gebruiker '$gebruikersnaam' kan niet worden gevonden.";
header('Refresh: 2; Url=/');
}
}
?>
if(isset($_POST['inloggen'])){
// DEFINITEER $GEBRUIKERSNAAM EN $WACHTWOORD \\
$gebruikersnaam = $_POST['gebruikersnaam'];
$wachtwoord = $_POST['wachtwoord'];
// BESCHERM DE GEGEVENS \\
$gebruikersnaam = $con->real_escape_string($gebruikersnaam);
$wachtwoord = md5($wachtwoord);
// LOGIN SCRIPT \\
$result = $con->query("SELECT * FROM `leden` WHERE `gebruikersnaam`='$gebruikersnaam'")->fetch_array(); // SELECTEER ALLE DATA VAN DE GEBRUIKERSNAAM \\
if (( $gebruikersnaam ) == ( $result['gebruikersnaam'] )){
if (( $wachtwoord ) == ( $result['wachtwoord'] )){
$id = $con->query("SELECT `id` FROM `leden` WHERE `gebruikersnaam`='$gebruikersnaam'")->fetch_array();
$_SESSION['id'] = $id['id'];
header('Location: /dashboard');
}
else{
$error = "Er is een fout wachtwoord ingevoerd voor de gebruiker '$gebruikersnaam'.";
header('Refresh: 2; Url=/');
}
}
else{
$error = "De gebruiker '$gebruikersnaam' kan niet worden gevonden.";
header('Refresh: 2; Url=/');
}
}
?>
functions.php
Code (php)
site_status.php
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
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<?php
$result = $con->query("SELECT * FROM `instellingen`")->fetch_array();
$maintenanceMode = $result['status'];
$maintananceGlobal = $result['status2'];
$maintenanceLocations = $result['status3'];
$maintenanceMessage = "<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<title>Onderhoud Modus</title>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js'></script>
<script type='text/javascript'>
$(document).ready(function() {
var id = '#dialog';
//Get the screen height and width
var maskHeight = $(document).height();
var maskWidth = $(window).width();
//Set heigth and width to mask to fill up the whole screen
$('#mask').css({'width':maskWidth,'height':maskHeight});
//transition effect
$('#mask').fadeIn(1000);
$('#mask').fadeTo('slow',0.8);
//transition effect
$(id).fadeIn(2000);
var fields = document.getElementById('disable').getElementsByTagName('*');
for(var i = 0; i < fields.length; i++)
{
fields[i].disabled = true;
}
});
</script>
<style type='text/css'>
body {
font-family:verdana;
font-size:15px;
}
#overlay {
position: fixed;
height: 100%;
width: 100%;
z-index: 1000000;
background: url('link/to/semitransparent.png');
}
a {color:#333; text-decoration:none}
a:hover {color:#ccc; text-decoration:none}
#mask {
position:absolute;
left:0;
top:0;
z-index:9000;
background-color:#000;
display:none;
}
#boxes .window {
position:absolute;
left:0;
top:0;
width:340px;
height:200px;
display:none;
z-index:9999;
padding:20px;
}
#boxes #dialog {
width: 350px;
height: 200px;
background-color: white;
position: absolute !important;
top:0 !important;
bottom: 0 !important;
left: 0 !important;
right: 0 !important;
margin: auto !important;
}
</style>
</head><body>
<div id='boxes'>
<div style='top: 199.5px; left: 551.5px; display: none;' id='dialog' class='window'>
<b style='font-size: 15pt;'><center>Onderhoud</center></b>Momenteel is het paneel in onderhoud, hierom is gebruik maken van het paneel niet mogelijk. Deze onderhoud is waarschijnlijk snel voorbij. <br><br><b>- Het Beheer</b>
</div>
<div style='width: 1478px; height: 602px; display: none; opacity: 0.8;' id='mask'></div>
</div>
</body>
</html>
";
if (($maintenanceMode) == "onderhoud")
{
if (($maintananceGlobal) == "niet_overal")
{
if (($currentLocation) == ($maintenanceLocations))
{
echo $maintenanceMessage;
}
}
else
{
echo $maintenanceMessage;
}
}
?>
$result = $con->query("SELECT * FROM `instellingen`")->fetch_array();
$maintenanceMode = $result['status'];
$maintananceGlobal = $result['status2'];
$maintenanceLocations = $result['status3'];
$maintenanceMessage = "<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<title>Onderhoud Modus</title>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js'></script>
<script type='text/javascript'>
$(document).ready(function() {
var id = '#dialog';
//Get the screen height and width
var maskHeight = $(document).height();
var maskWidth = $(window).width();
//Set heigth and width to mask to fill up the whole screen
$('#mask').css({'width':maskWidth,'height':maskHeight});
//transition effect
$('#mask').fadeIn(1000);
$('#mask').fadeTo('slow',0.8);
//transition effect
$(id).fadeIn(2000);
var fields = document.getElementById('disable').getElementsByTagName('*');
for(var i = 0; i < fields.length; i++)
{
fields[i].disabled = true;
}
});
</script>
<style type='text/css'>
body {
font-family:verdana;
font-size:15px;
}
#overlay {
position: fixed;
height: 100%;
width: 100%;
z-index: 1000000;
background: url('link/to/semitransparent.png');
}
a {color:#333; text-decoration:none}
a:hover {color:#ccc; text-decoration:none}
#mask {
position:absolute;
left:0;
top:0;
z-index:9000;
background-color:#000;
display:none;
}
#boxes .window {
position:absolute;
left:0;
top:0;
width:340px;
height:200px;
display:none;
z-index:9999;
padding:20px;
}
#boxes #dialog {
width: 350px;
height: 200px;
background-color: white;
position: absolute !important;
top:0 !important;
bottom: 0 !important;
left: 0 !important;
right: 0 !important;
margin: auto !important;
}
</style>
</head><body>
<div id='boxes'>
<div style='top: 199.5px; left: 551.5px; display: none;' id='dialog' class='window'>
<b style='font-size: 15pt;'><center>Onderhoud</center></b>Momenteel is het paneel in onderhoud, hierom is gebruik maken van het paneel niet mogelijk. Deze onderhoud is waarschijnlijk snel voorbij. <br><br><b>- Het Beheer</b>
</div>
<div style='width: 1478px; height: 602px; display: none; opacity: 0.8;' id='mask'></div>
</div>
</body>
</html>
";
if (($maintenanceMode) == "onderhoud")
{
if (($maintananceGlobal) == "niet_overal")
{
if (($currentLocation) == ($maintenanceLocations))
{
echo $maintenanceMessage;
}
}
else
{
echo $maintenanceMessage;
}
}
?>
Bedankt voor jullie reacties voor het veilig te maken! PS: ik gebruik md5 omdat ik het fijn vind om te gebruiken en password_hash() werkt op een of andere manier niet.
Gewijzigd op 04/12/2016 16:30:01 door - Rob -
Verder zou ik bij een foute inlogpoging niet vermeldde of de gebruikersnaam óf het wachtwoord fout is. Maar toon liever dat één of beiden fout is. Je wilt het account-kapers (hackers) niet makkelijk maken om een account over te nemen.
Verder zou een brute-force detectie een handige maatregel zijn, zodat het inloggen op je account een poosje geblokkeerd is na xx aantal foutieve inlogpogingen.
En eventueel kan je de gebruiker de keuze geven voor Two-Factor Authentication, zodat hij bijv. met SMS of Google Authenticator op zijn tablet/smartphone zijn inlogactie moet bevestigen.
- Sla geen onderhoudsstatus op in de database. Stel je voor dat je MySQL-server problemen heeft. Dan kan je jouw site niet eventjes netjes uitschakelen, tot het probleem is verholpen.
- Ik zie een paar variabelen die niet ge-echo'd worden.
En een heel belangrijke:
Zet je datafile.ini BUITEN je webroot!!!!!!
Gewijzigd op 04/12/2016 17:41:03 door - Ariën -
- Ariën - op 04/12/2016 17:27:35:
Ziet er aardig veilig uit, maar waarom zoek je niet uit waarom password_hash() niet werkt? MD5 is tegenwoordig zeer kwetsbaar.
Verder zou ik bij een foute inlogpoging niet vermeldde of de gebruikersnaam óf het wachtwoord fout is. Maar toon liever dat één of beiden fout is. Je wilt het account-kapers (hackers) niet makkelijk maken om een account over te nemen.
Verder zou een brute-force detectie een handige maatregel zijn, zodat het inloggen op je account een poosje geblokkeerd is na xx aantal foutieve inlogpogingen.
En eventueel kan je de gebruiker de keuze geven voor Two-Factor Authentication, zodat hij bijv. met SMS of Google Authenticator op zijn tablet/smartphone zijn inlogactie moet bevestigen.
- Sla geen onderhoudsstatus op in de database. Stel je voor dat je MySQL-server problemen heeft. Dan kan je jouw site niet eventjes netjes uitschakelen, tot het probleem is verholpen.
- Ik zie een paar variabelen die niet ge-echo'd worden.
En een heel belangrijke:
Zet je datafile.ini BUITEN je webroot!!!!!!
Verder zou ik bij een foute inlogpoging niet vermeldde of de gebruikersnaam óf het wachtwoord fout is. Maar toon liever dat één of beiden fout is. Je wilt het account-kapers (hackers) niet makkelijk maken om een account over te nemen.
Verder zou een brute-force detectie een handige maatregel zijn, zodat het inloggen op je account een poosje geblokkeerd is na xx aantal foutieve inlogpogingen.
En eventueel kan je de gebruiker de keuze geven voor Two-Factor Authentication, zodat hij bijv. met SMS of Google Authenticator op zijn tablet/smartphone zijn inlogactie moet bevestigen.
- Sla geen onderhoudsstatus op in de database. Stel je voor dat je MySQL-server problemen heeft. Dan kan je jouw site niet eventjes netjes uitschakelen, tot het probleem is verholpen.
- Ik zie een paar variabelen die niet ge-echo'd worden.
En een heel belangrijke:
Zet je datafile.ini BUITEN je webroot!!!!!!
Waar zet ik hem buiten mijn webroot? een ander domein of??
Quote:
- Sla geen onderhoudsstatus op in de database. Stel je voor dat je MySQL-server problemen heeft. Dan kan je jouw site niet eventjes netjes uitschakelen, tot het probleem is verholpen.
Dankzij jouw script kan ik het nu via .ini laten lopen :D Zodat er geen MySQL-server nodig is. Heb je toevallig nog een link liggen naar een goede manier voor brute-force tegen te gaan? Zodat ik er meer uit kan leren en toepassen :D
Gewijzigd op 04/12/2016 18:11:53 door - Rob -
Je slaat dat bestand op in een hoger op in een map. Dus buiten /public_html of waar je webserver je site maar ook opzoekt. Niemand mag het dus kunnen bekijken via de browser.
- Ariën - op 04/12/2016 18:11:37:
Je slaat dat bestand op in een hoger op in een map. Dus buiten /public_html of waar je webserver je site maar ook opzoekt. Niemand mag het dus kunnen bekijken via de browser.
Ik heb hem op localhost voor nu, maar dus op webserver buiten /private_html en hoe moet ik hem dan pakken? met ../?
Gewijzigd op 04/12/2016 18:16:52 door - Rob -
Gewijzigd op 04/12/2016 18:17:43 door - Ariën -
- Ariën - op 04/12/2016 18:15:30:
Is /private_html niet de beste plek?
Hoe bedoel je?
Met ../private_html/datafile.ini kan je hem dan openen.
- Ariën - op 04/12/2016 18:19:10:
Private = prive = niet openbaar ;-)
Met ../private_html/datafile.ini kan je hem dan openen.
Met ../private_html/datafile.ini kan je hem dan openen.
Even kijken, maar hoe include ik dat dan bij alles? Want bij de config.php include ik hem maar in een volgende map include die m niet meer
Toevoeging op 04/12/2016 18:23:24:
En bij /private_html kan j hem nog steeds lezen
En in welke map leest je webserver? Normaal is dat /htdocs, /public_html of /www. Die /private_html hoort daar NIET in te staan.
Gewijzigd op 04/12/2016 18:27:55 door - Ariën -
- Ariën - op 04/12/2016 18:27:28:
Sla die locatie op in variabele. Dan hoef je het pad naar datefile.ini niet steeds op vele plekken in je code te wijzigen.
En in welke map leest je webserver? Normaal is dat /htdocs, /public_html of /www. Die /private_html hoort daar NIET in te staan.
En in welke map leest je webserver? Normaal is dat /htdocs, /public_html of /www. Die /private_html hoort daar NIET in te staan.
private_html staat op webserver door SSL, maar hoe bedoel je precies? [qoute]Sla die locatie op in variabele. Dan hoef je het pad naar datefile.ini niet steeds op vele plekken in je code te wijzigen.[/quote]
Wordt die voor SSL gebruikt? Dan kan je beter een andere map gebruiken BOVEN je /public_html. /data bijvoorbeeld.
- Ariën - op 04/12/2016 18:34:59:
Wordt die voor SSL gebruikt? Dan kan je beter een andere map gebruiken BOVEN je /public_html. /data bijvoorbeeld.
Maar alles staat in die private_html, alle bestanden. Hoe kan ik dan vanuit /private_html naar /public_html/data gaan? Ook kan ik geen link/variable zetten in e volgende code:
Code (php)
1
2
3
4
2
3
4
$setting = parse_ini_file('datafile.ini');
dus ik kan niet
$setting = parse_ini_file('http://DOMEIN.NL/BESTAND.php'); doen of
$url = "http://DOMEIN.NL/BESTAND.php" $setting = parse_ini_file($url);
dus ik kan niet
$setting = parse_ini_file('http://DOMEIN.NL/BESTAND.php'); doen of
$url = "http://DOMEIN.NL/BESTAND.php" $setting = parse_ini_file($url);
Toevoeging op 04/12/2016 20:56:48:
Als je meer dan 3 keer fout hebt ingelogd. :D Na 10 minuten hoef je geen reCAPTCHA meer in te vullen.
Nu alleen nog maken dat als je succesvol bent ingelogd, dat als je uitlogd in die 10 minuten, je geen reCAPTCHA meer hoeft intevullen. Dus bruteforce kan niet meer
Gewijzigd op 04/12/2016 21:04:38 door - Rob -
/public_html = Onbeveiligd via http.
Zet je site in een van beiden en de data in een bovenste directory /data.
Verder is Captcha bij elke inlog wel een beetje vervelend. Plus dat dit door bots al valt uit te lezen.
- Ariën - op 04/12/2016 22:12:20:
/private_html = Beveiligd via SSL
/public_html = Onbeveiligd via http.
Zet je site in een van beiden en de data in een bovenste directory /data.
Verder is Captcha bij elke inlog wel een beetje vervelend. Plus dat dit door bots al valt uit te lezen.
/public_html = Onbeveiligd via http.
Zet je site in een van beiden en de data in een bovenste directory /data.
Verder is Captcha bij elke inlog wel een beetje vervelend. Plus dat dit door bots al valt uit te lezen.
Niet bij elke inlog, als je inlogd, of de capatcha goed invult krijg je hem niet meer. Tenzij je weer 3 foute inlog pogingen doet
Dus bots die re-captcha uit kunnen lezen kunnen lekker brute-forcen. Gewoon op IP-adres tijdelijk blokkeren.
- Ariën - op 04/12/2016 22:45:57:
Dus bots die re-captcha uit kunnen lezen kunnen lekker brute-forcen. Gewoon op IP-adres tijdelijk blokkeren.
Hoe doe ik dat, ik kan toch ook gewoon die captcha weghalen en dat je na 5 minuten pas weer toegang hebt?
Gewijzigd op 04/12/2016 23:00:57 door - Rob -
Code (php)
1
2
3
2
3
<?php
$result = $con->query("SELECT * FROM `leden` WHERE `gebruikersnaam`='$gebruikersnaam'")->fetch_array();
?>
$result = $con->query("SELECT * FROM `leden` WHERE `gebruikersnaam`='$gebruikersnaam'")->fetch_array();
?>
Dit geeft foutmeldingen wanneer er iets met de tabel leden niet in de haak is. De volgorde wat je hier doet:
a) $con->query()
b) op datgene dat je van query() terugkrijgt de method fetch_array() aanroepen.
Maar wat nu als query() een FALSE terug geeft omdat je query mislukt is? FALSE->fetch_array() gaat niet werken he.
dus:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
$result = $con->query("SELECT * FROM `leden` WHERE `gebruikersnaam`='$gebruikersnaam'");
if(FALSE === $result) {
// de query is mislukt.
echo 'Er gaat iets mis!';
exit;
}
// de query is geslaagd dus we gaan weer een stapje verder
$row = $result->fetch_assoc();
if(NULL === $row) {
// de query is geslaagd maar er zijn geen rijen gevonden die aan de query voldeden.
echo 'Login failed';
exit;
}
?>
$result = $con->query("SELECT * FROM `leden` WHERE `gebruikersnaam`='$gebruikersnaam'");
if(FALSE === $result) {
// de query is mislukt.
echo 'Er gaat iets mis!';
exit;
}
// de query is geslaagd dus we gaan weer een stapje verder
$row = $result->fetch_assoc();
if(NULL === $row) {
// de query is geslaagd maar er zijn geen rijen gevonden die aan de query voldeden.
echo 'Login failed';
exit;
}
?>
Verder zou een stukje CSRF bescherming in een login formulier ook niet misstaan.
MD5 Mag je gewoon niet meer gebruiken voor user passwords.
Geef geen helpende informatie weg bij een login formulier:
Mooi dan ga ik verder met de volgende naam. (Rainbow table)
ini en config files buiten je webroot houden
Andere think-overs:
- Gebruik TLS encryptie voor je website
- Eis een minimale wachtwoord sterkte van je gebruikers (bijv. minimale lengte 8, Minimaal 1 hoofdletter, 1 kleine letter en 1 ander leesteken)
- Twee weg identificatie
- Waarom gebruikersnamen? kan je niet met mailadressen werken?
- Moet een email en/of gebruikersnaam uniek zijn in de tabel users?
- beveilig je FTP, dashboard en Mysql server ook met een sterk wachtwoord.
Code (php)
1
2
3
4
5
2
3
4
5
<?php
// SERVER INSTELLINGEN \\
$_SERVER['admin'] = $setting['admin'];
$_SERVER['admin_ip'] = $setting['admin_ip'];
?>
// SERVER INSTELLINGEN \\
$_SERVER['admin'] = $setting['admin'];
$_SERVER['admin_ip'] = $setting['admin_ip'];
?>
Waaaaaaat? Waarom settings in een superglobal zetten ??? wat is hier het nut van?
Muggenziften:
- inline css :-(
- fetch_array() gebruikt twee keer zoveel resources dan fetch_assoc()
Gewijzigd op 04/12/2016 23:43:36 door Frank Nietbelangrijk
Rob Chesture op 04/12/2016 23:00:01:
Hoe doe ik dat, ik kan toch ook gewoon die captcha weghalen en dat je na 5 minuten pas weer toegang hebt?
- Ariën - op 04/12/2016 22:45:57:
Dus bots die re-captcha uit kunnen lezen kunnen lekker brute-forcen. Gewoon op IP-adres tijdelijk blokkeren.
Hoe doe ik dat, ik kan toch ook gewoon die captcha weghalen en dat je na 5 minuten pas weer toegang hebt?
Bij elke foutieve inlog sla je het IP op, de userID van het account en het aantal keer dat er geprobeerd is. Als dat gelijk of hoger is dan 5 bijvoorbeeld, dan blokkeer je het account op dat IP.
Maar de genoemde Two Factor authentication als extraatje is ook te te waarderen voor gebruikers. Vooral als het account voor belangrijke (zoals bedrijfsgevoelige) informatie gebruikt wordt. Net zo iets als de RaboScanner of de ABN reader.
Gewijzigd op 04/12/2016 23:38:16 door - Ariën -
Check je daar ook of de gebruiker ingelogd is? (en zo nee, stuur je hem dan terug naar het inlogscript).
en op regel 12 en 15 van je inlogfunctie voer je dezelfde query uit.
Op regel 13 zit het id dus in $result['id']
beetje zinloos om dat nog een keer uit te voeren om in $id['id'] dezelfde waarde te stoppen.
Ivo P op 05/12/2016 09:55:29:
ik mis nog de inhoud van het script waar je op komt na header('Location: /dashboard')
Check je daar ook of de gebruiker ingelogd is? (en zo nee, stuur je hem dan terug naar het inlogscript).
en op regel 12 en 15 van je inlogfunctie voer je dezelfde query uit.
Op regel 13 zit het id dus in $result['id']
beetje zinloos om dat nog een keer uit te voeren om in $id['id'] dezelfde waarde te stoppen.
Check je daar ook of de gebruiker ingelogd is? (en zo nee, stuur je hem dan terug naar het inlogscript).
en op regel 12 en 15 van je inlogfunctie voer je dezelfde query uit.
Op regel 13 zit het id dus in $result['id']
beetje zinloos om dat nog een keer uit te voeren om in $id['id'] dezelfde waarde te stoppen.
Daar check ik of de gebruiker ingelogd is. als dat niet zo is wordt hij/zij teruggestuurd.
Toevoeging op 05/12/2016 15:24:46:
Quote:
Bij elke foutieve inlog sla je het IP op, de userID van het account en het aantal keer dat er geprobeerd is. Als dat gelijk of hoger is dan 5 bijvoorbeeld, dan blokkeer je het account op dat IP.
Is niet al te handig, hiermee wordt elke keer als je page reload de query uitgevoerd. Dus als ze dan ook nog page_reload in brute_force zetten, kan de server nog steeds overbelast worden.