Scripts

Simpel, veilig login systeempje

Basis script wat je kan uitbouwen tot bijv. een ledensysteem. Je kan maximaal 3 keer proberen in te loggen, daarna wordt je IP geblokkeerd. Het script maakt gebruik van MySQLi. Graag ontvang ik opbouwende kritiek hoe ik dit systeem veiliger kan maken! (niet beginnen over ssl :) V1.0.1: -query aangepast voor controleren of je gebant bent: "HOUR(TIMEDIFF(NOW(), time)) < 24 " >> " time > (NOW() - INTERVAL 24 HOUR)" -fetch_array veranderd naar fetch_assoc -session start weg gehaald -Quotes aangepast -tabel rij naam: time >> date_time -tabel rij naam: host >> sys_info -query's "overzichtelijke" gemaakt -unieke waarde gemaakt van de rij "gebruikersnaam" -uniqid in hash toegevoegd -database-model aangepast Laatste update 28-11-2009

simpel-veilig-login-systeempje
///////////// config.inc.php ////////////////
<?php
/**
 * @author Arwin van der Velden
 * @copyright 2009
 * @name config.inc.php
 * @version 1.0.1
 */

$db['username']     = '';
$db['password']     = '';
$db['host']        = 'localhost';
$db['database']    = '';

$settings['db_gebruikers_table'] = 'gebruikers';
$settings['db_sessions_table'] = 'sessions';
$settings['db_login_attempts_table'] = 'login_attempts';

$settings['max_login_pogingen'] = '3';


$mysqli = new mysqli($db['host'], $db['username'], $db['password'], $db['database']); // Host - Username - Password - Database
if(mysqli_connect_errno())
{
    trigger_error('Fout bij verbinding: '.$mysqli->error);
} 
unset($db);
include('functies.inc.php');
?>


///////////// functies.inc.php ////////////////
<?php
/**
 * @author Arwin van der Velden
 * @copyright 2009
 * @name functies.inc.php
 * @version 1.0.1
 */
function isingelogd(){
	global $settings, $mysqli;
    // Kijken of er cookies zijn gezet, en controleren of ze valid zijn
    if(isset($_COOKIE['user_id']) && ctype_digit($_COOKIE['user_id']) && isset($_COOKIE['user_hash']) && ctype_alnum($_COOKIE['user_hash'])) {
        $query = "	SELECT 
						gebruikerID, hash_key 
					FROM 
						".$settings['db_sessions_table']." 
					WHERE 
						gebruikerID = '".$mysqli->real_escape_string($_COOKIE['user_id'])."' 
					AND 
						hash = '".$mysqli->real_escape_string($_COOKIE['user_hash'])."' 
					AND 
						ip = '".$mysqli->real_escape_string($_SERVER['REMOTE_ADDR'])."'";
        
        // Query uitvoeren
		if ($result = $mysqli->query($query)) {

			$userId = $result->fetch_assoc();

            if(ctype_digit($userId['gebruikerID'])) {
                // Controleren of de hash ook klopt (browsercheck)
                if(sha1($_COOKIE['user_id'] . $_SERVER['HTTP_USER_AGENT'] . $userId['hash_key']) == $_COOKIE['user_hash']) {
                    return true;
                } else { // Browser is veranderd
                    // Niet ingelogd
					$query = "	UPDATE 
									".$settings['db_sessions_table']." 
								SET 
									hash = NULL, 
									hash_key = NULL, 
									ip = '".$mysqli->real_escape_string($_SERVER['REMOTE_ADDR'])."' 
								WHERE 
									gebruikerID = '".$mysqli->real_escape_string($_COOKIE['user_id'])."'";
					
					$mysqli->query($query);
					
					// Cookies verwijderen
                    setcookie('user_id', 0, time() - 3600, '/');
                    setcookie('user_hash', '', time() - 3600, '/');        
                    return false;	                     
                }
                
            }   
		}     
        
    } else {    
    	// Geen geldige cookies gezet
        // Niet ingelogd
        return false;
    }        
}  
?>

///////////// index.php (login pagina)////////////////
<?php
/**
 * @author Arwin van der Velden
 * @copyright 2009
 * @name index.php
 * @version 1.0.1
 */
error_reporting(E_ALL);
ini_set('display_errors', '1');
include('config.inc.php');

/* ----------------------------------------------------------------------------------------------- */		
if(!isingelogd()) {
	// Anti-flood, na 5 keer verkeerd inloggen wordt je IP adres 24 uur geband
	$query = "	SELECT 
					COUNT(id) AS attempts 
				FROM 
					".$settings['db_login_attempts_table']." 
				WHERE 
					date_time > (NOW() - INTERVAL 24 HOUR) 
				AND 
					ip = '".$mysqli->real_escape_string($_SERVER['REMOTE_ADDR'])."' 
				AND 
					sys_info = '".$mysqli->real_escape_string($_SERVER['HTTP_USER_AGENT'])."'";
	
	if ($result = $mysqli->query($query)) {	
		$login_attempt = $result->fetch_assoc();
		
		if($login_attempt['attempts'] > $settings['max_login_pogingen']) { // Controleren of je bent geband
			echo 'U bent tijdelijk geband<br>';
		} else {
	
			if (mb_strtoupper($_SERVER['REQUEST_METHOD']) != 'POST') {						
				$formulier = true;
			} else {						
				$formulier = false;					
				if(ctype_digit($_POST['form']) && time() < strtotime("+1 minute", $_POST['form'])) { 				
					$username = htmlspecialchars($_POST['username']);
					$hashedPass = sha1($username.$_POST['pass']);
			 
			        $query = "	SELECT 
									ID 
								FROM 
									".$settings['db_gebruikers_table']." 
								WHERE 
									gebruikersnaam = '".$mysqli->real_escape_string($username)."' 
								AND 
									wachtwoord = '".$mysqli->real_escape_string($hashedPass)."'";
			
					if ($result = $mysqli->query($query)) {
			
						$userId = $result->fetch_assoc();
			
				        if(ctype_digit($userId['ID'])) {		
				        	$hash_key = uniqid(mt_rand(), true);
				            $hash = sha1($userId['ID'] . $_SERVER['HTTP_USER_AGENT'] . $hash_key);
				            // Cookies maken
				            setcookie('user_id', $userId['ID'], time() + 60*60*24*365, '/');
				            setcookie('user_hash', $hash, time() + 60*60*24*365, '/');            
				            // Update query samenstellen, ip en hash updaten
				         $sql = "	INSERT INTO 
						 				".$settings['db_sessions_table']." 
										(
											gebruikerID, 
											hash, 
											hash_key,
											datum, 
											ip
										) 
									VALUES ( 
										'".$mysqli->real_escape_string($userId['ID'])."', 
										'".$hash."', 
										'".$hash_key."', 
										NOW(), 
										'".$mysqli->real_escape_string($_SERVER['REMOTE_ADDR'])."'
									)";
				            // Query uitvoeren			
							if(!$result = $mysqli->query($sql))	{
							    trigger_error('Fout in query: '.$mysqli->error);
							} else {
							    if($mysqli->affected_rows > 0) { 
							    	echo 'Je bent ingelogd!';
							    }
							}									        
				        } else {				        	
				        	$sql = "	INSERT INTO 
											".$settings['db_login_attempts_table']." 
											(
												date_time, 
												ip, 
												sys_info
											) 
										VALUES ( 
											NOW(), 
											'".$mysqli->real_escape_string($_SERVER['REMOTE_ADDR'])."', 
											'".$mysqli->real_escape_string($_SERVER['HTTP_USER_AGENT'])."'
										)";				            
			
							if(!$result = $mysqli->query($sql)) {
							    trigger_error('Fout in query: '.$mysqli->error);
							}/*else {
							    if($mysqli->affected_rows > 0) { 
							    	echo 'Attempt ingevoerd<br>';
							    }
							}
				        	*/
							echo 'Het wachtwoord of gebruikersnaam was incorrect';
							$formulier = true;
						}
			
					} 
					
				} else {
					echo 'Fout bij inloggen. Probeer het opnieuw.';
				}
			
			}
			if($formulier) {
				echo '	<form method="post" action="'.end(explode('/', $_SERVER["REQUEST_URI"])).'"> 				
					<p><label>Username:</label><input type="text" name="username" value="" /></p>
					<p><label>Password:</label><input type="password" name="pass" value="" /></p>
					<br><input type="hidden" name="form" value="'.time().'" />						
					<p><input type="submit" value="Inloggen" /></p>						
					</form>
				';				
			}
			}
	} else {
		trigger_error('Fout in query: '.$mysqli->error);
	}
 
} else {
	echo 'U bent al ingelogd.';
}
?>


///////////// logout.php ////////////////
<?php
/**
 * @author Arwin van der Velden
 * @copyright 2009
 * @name logout.php
 * @version 1.0.1
 */
include('config.inc.php');

setcookie('user_id', 0, time() - 3600, '/');
setcookie('user_hash', '', time() - 3600, '/'); 

$query = "	UPDATE 
				".$settings['db_sessions_table']." 
			SET 
				hash = NULL, 
				hash_key = NULL, 
				ip = '".$mysqli->real_escape_string($_SERVER['REMOTE_ADDR'])."' 
			WHERE 
				gebruikerID = '".$mysqli->real_escape_string($_COOKIE['user_id'])."'";

if(!$result = $mysqli->query($query)) {
    trigger_error('Fout in query: '.$mysqli->error);
} else {
    if($mysqli->affected_rows > 0) {
        echo 'U bent uitgelogd';
    }
}     
?>


/////////////// voorbeeld beveiligde pagina ///////////////
<?php 
include('config.inc.php');
if(!isingelogd()) {
	echo "Je moet eerst inloggen om deze pagina te zien!";
} else {
	echo "Je zit in de beveiligde pagina!";
}
?>

/////////////// voorbeeld registratie script ///////////////
<?php
include('config.inc.php');	
if ($_SERVER['REQUEST_METHOD'] != 'POST') {						
	$formulier = true;
} else {						
	$formulier = false;	
	//controles uitvoeren	
	
	if(!ereg("^[A-Za-z0-9]+$",$_POST["username"]) || strlen($_POST["username"]) < 3) {
		echo '<b style="color:#FDB839">&#8226; Uw gebruikersnaam is ongeldig.</b><br>';	
		$_POST["Gebruikersnaam"] = ""; $formulier = true;	
	} 
	
	$result = $mysqli->query("SELECT ID FROM ".$settings['db_gebruikers_table']." WHERE gebruikersnaam LIKE '".$mysqli->real_escape_string($_POST['username'])."'");
	
	if(!empty($_POST["username"]) && $result->num_rows > 0) {	
		echo '<b style="color:#FDB839">&#8226; Deze gebruikersnaam is al bezet.</b><br>';	
		$_POST["Gebruikersnaam"] = ""; $formulier = true;	
	}
	
	if(empty($_POST["pass"])) {	
		echo '<b style="color:#FDB839">&#8226; Uw password is ongeldig.</b><br>';	
		$_POST["pass"] = ""; $formulier = true;	
	}

	if(empty($_POST["email"]) || preg_match("/^[A-Za-z0-9._\-]+\@[A-Za-z0-9._\-]+\.[A-Za-z]{2,4}$/", $_POST["email"])) {	
		echo '<b style="color:#FDB839">&#8226; Uw emailadres is ongeldig.</b><br>';	
		$_POST["email"] = ""; $formulier = true;	
	}			

	if($formulier) { 	// Wel of niet verzenden
		echo '<br>';	
		$_POST["pass"] = "";
	} else { // Verzenden
		
		$sql = "
		    INSERT INTO ".$settings['db_gebruikers_table']." (
		        gebruikersnaam,
		        wachtwoord,
				voornaam,
				achternaam,
				emailadres,
				ipadres,
				startdatum )
		    VALUES (
		        '".$mysqli->real_escape_string(htmlspecialchars($_POST['username']))."',
		        '".$mysqli->real_escape_string(sha1(htmlspecialchars($_POST['username']).$_POST['pass']))."',
		        '".$mysqli->real_escape_string(htmlspecialchars($_POST['fname']))."',
		        '".$mysqli->real_escape_string(htmlspecialchars($_POST['lname']))."',
		        '".$mysqli->real_escape_string($_POST['email'])."',
		        '".$mysqli->real_escape_string($_SERVER['REMOTE_ADDR'])."',
		        NOW() 
		    )";
		
		if(!$result = $mysqli->query($sql))	{
		    trigger_error('Fout in query: '.$mysqli->error);
		    echo '<br />Er is een fout opgetreden, de gebruiker is niet toegevoegd.';
		} else {
		    echo 'De gebruiker is succesvol toegevoegd.';
		} 	
		
		
	}

}



if($formulier) {
	echo '	<form method="post" action="'.end(explode('/', $_SERVER["REQUEST_URI"])).'"> 				
		<p><label>Username:</label><input type="text" name="username" value="" /></p>
		<p><label>Password:</label><input type="password" name="pass" value="" /></p>
		<p></p>
		<p><label>First Name:</label><input type="text" name="fname" value="" /></p>
		<p><label>Last Name:</label><input type="text" name="lname" value="" /></p>
		<p><label>E-mail Address:</label><input type="text" name="email" value="" /></p>
			
		<p><input type="submit" value="Send form" /></p>						
		</form>
	';				
}

 
?>
/////////////// DATABASE ///////////////
CREATE TABLE `gebruikers` (
  `ID` int(11) NOT NULL auto_increment,
  `gebruikersnaam` varchar(90) NOT NULL,
  `wachtwoord` varchar(255) NOT NULL,
  `voornaam` varchar(255) NOT NULL,
  `tussenvoegsel` varchar(255) NOT NULL,
  `achternaam` varchar(255) NOT NULL,
  `emailadres` varchar(255) NOT NULL,
  `rechten` int(11) NOT NULL,
  `ip` varchar(16) NOT NULL,
  `startdatum` datetime NOT NULL,
  `bevestigen` varchar(45) NOT NULL,
  PRIMARY KEY  (`ID`),
  UNIQUE KEY `gebruikersnaam` (`gebruikersnaam`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 ;

CREATE TABLE `sessions` (
  `sessionID` int(11) NOT NULL auto_increment,
  `gebruikerID` int(11) NOT NULL,
  `hash` varchar(40) NOT NULL,
  `hash_key` varchar(41) NOT NULL,
  `datum` datetime NOT NULL,
  `ip` varchar(16) NOT NULL,
  PRIMARY KEY  (`sessionID`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 ;

ALTER TABLE sessions ADD FOREIGN KEY ( gebruikerID ) REFERENCES gebruikers( ID ) ;

CREATE TABLE `login_attempts` (
  `id` int(11) NOT NULL auto_increment,
  `date_time` datetime NOT NULL,
  `ip` varchar(16) NOT NULL,
  `sys_info` varchar(610) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 ; 

Reacties

0
Nog geen reacties.