Система за сигурна авторизация(логин)

nasibg

Registered
Здравейте искам да си направя сигурна система за авторизация(логин). Която ще я ползвам за всеки един проект, та какви са несигурностите и нещо което може да се залъже и заобиколи? Много искам да я направя перфектна, като сигурност а за допълнителни трикове които също ще са от полза ясно ще ги направя. Но първо да я изградя и сле това ясно. Благодаря предварително! ;) +1 ето и кода:

index.php
Код:
<?php
include("config.php");
session_start();
if($_SERVER["REQUEST_METHOD"] == "POST")
{
$myusername=addslashes($_POST['username']); 
$mypassword=addslashes($_POST['password']); 
$sql="SELECT id FROM admin WHERE username='$myusername' and passcode='$mypassword'";
$result=mysql_query($sql);
$row=mysql_fetch_array($result);
$active=$row['active'];
$count=mysql_num_rows($result);
if($count==1)
{
session_register("myusername");
$_SESSION['login_user']=$myusername;
header("location: welcome.php");
}
else 
{
$error="Грешно име или парола";
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Вход</title>
</head>
<body>
<div align="center">
<div>
<div><b>Администрация</b></div>
<div>
<form method="post">
<label>Име: </label><input type="text" name="username"/><br /><br />
<label>Парола: </label><input type="password" name="password" /><br/><br />
<input type="submit" value="Влез"/><br />
</form>
<?php echo $error; ?>
</div>
</div>
</div>
</body>
</html>

lock.php

Код:
<?php
include('config.php');
session_start();
$user_check=$_SESSION['login_user'];

$ses_sql=mysql_query("select username from admin where username='$user_check' ");

$row=mysql_fetch_array($ses_sql);

$login_session=$row['username'];

if(!isset($login_session))
{
header("Location: index.php");
}
?>

welcome.php

Код:
<?php
include('lock.php');
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Добре дошъл <?php echo $login_session; ?></title>
</head>
<body>
<h2><a href="logout.php">Изход</a></h2>
 
като за начало, може да добавиш това в червеното...

<?php
include("config.php");
session_start();
if($_SERVER["REQUEST_METHOD"] == "POST")
{
$myusername=htmlspecialchars(addslashes($_POST['username']));
$mypassword=htmlspecialchars(addslashes($_POST['password']));
$sql="SELECT id FROM admin WHERE username='$myusername' and passcode='$mypassword'";
$result=mysql_query($sql);
$row=mysql_fetch_array($result);
$active=$row['active'];
$count=mysql_num_rows($result);
if($count==1)
{
session_register("myusername");
$_SESSION['login_user']=$myusername;
header("location: welcome.php");
}
else
{
$error="Грешно име или парола";
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Вход</title>
</head>
<body>
<div align="center">
<div>
<div><b>Администрация</b></div>
<div>
<form method="post">
<label>Име: </label><input type="text" name="username"/><br /><br />
<label>Парола: </label><input type="password" name="password" /><br/><br />
<input type="submit" value="Влез"/><br />
</form>
<?php echo $error; ?>
</div>
</div>
</div>
</body>
</html>

а също така за паролата може да приложиш някакво кодиране :) Защото така като гледам ще я сравняваш дирекнто със записа в базата данни, на който също не е приложено кодиране :)

А повече по темата за сигурност може да научиш тук

Редакция:

А също така навсякъде където инклудваш config.php, за по-голяма сигурност инклудвай така (това спира директното отваряне на config.php):
Код:
<?php
define('IN_VALID', true);
include("include.php");
?>

а в config.php сложи (най-отогре във файла):
Код:
if(!defined('IN_VALID')) { 
header("Location: index.php"); 
}
 
Има ли още желаещи да помогнат? :) смятам че има още какво да се желае по сигурността(само без PDO). А и като се логна и отида на индекса ми показва логин формата. А и във lock.php не трябва ли да има mysql_real_escape_string?
<?php
define('IN_VALID', true);
include("config.php");
session_start();
$user_check=mysql_real_escape_string($_SESSION['login_user']);

$ses_sql=mysql_query("select username from admin where username='$user_check' ");

$row=mysql_fetch_array($ses_sql);

$login_session=$row['username'];

if(!isset($login_session))
{
header("Location: index.php");
}
?>
Наистина се нуждая от помощта Ви! ;) Който най-добре се е справил, получава точка.(Не е въпроса за точката, а самата помощт! :) ).[/code]
 
А и като се логна и отида на индекса ми показва логин формата.


Код:
index.php
		
	
<?php
include("config.php");
session_start();
if($_SERVER["REQUEST_METHOD"] == "POST")
{
$myusername=addslashes($_POST['username']);
$mypassword=addslashes($_POST['password']);
$sql="SELECT id FROM admin WHERE username='$myusername' and passcode='$mypassword'";
$result=mysql_query($sql);
$row=mysql_fetch_array($result);
$active=$row['active'];
$count=mysql_num_rows($result);
if($count==1)
{
session_register("myusername");
$_SESSION['login_user']=$myusername;
header("location: welcome.php");
}
else
{
$error="Грешно име или парола";
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Вход</title>
</head>
<body>
<div align="center">
<div>
<div><b>Администрация</b></div>
<div><?php
$username=$_SESSION['login_user'];
if($username==NULL)
{
	echo'
	<form method="post">
	<label>Име: </label><input type="text" name="username"/><br /><br />
	<label>Парола: </label><input type="password" name="password" /><br/><br />
	<input type="submit" value="Влез"/><br />
	</form>';
}
else
{
	echo"Добре дошъл $username.";
}
?>
<?php echo $error; ?>
</div>
</div>
</div>
</body>
</html>


Така няма да ти се показва. :)
 
Ако искаш наистина сигурна автентикация, откажи се да го правиш на application ниво. Направи клиентска SSL автентикация, направи си CA и подписвай клиентски сертификати на потребителите си. Евентуална брутфорс атака най-вероятно няма да завърши преди вселената да до стигне фазата, при която всичката материя ще бъде под формата на черни дупки. Няма никакъв шанс нещо да се изслухти по мрежата. Единственият начин е лошите да се сдобият с клиентският ключ и сертификат. Само сертификатът не им е достатъчен, трябва им и ключа.

За наистина сигурни системи, ключът се пази на някаква смарт карта. Примерно универсалният електронен подпис дето го изкарват в България, представлява частен ключ върху смарт карта и съответния сертификат, подписан от някое от одобрените от КРС authority-ta (инфонотари, банксервиз и т.н.). Някои от сайтовете на държавната администрация те автентицират на базата на това, примерно сайта на НАП. Успех да се представиш за някой друг и да пуснеш от негово име данъчна декларация...освен ако не му откраднеш картата и сертификата.

Другото предимство е че на сървъра не се пазят никакви потребителски credentials. И да хакнеш сървъра и да се сдобиеш с административен достъп, нищо няма да направиш. Виж, ако хакнеш CA-то и се сдобиеш с ключа, с който се подписват клиентските сертификати, можеш да направиш много лоши неща. Но пък трябва да си идиот, за да го държиш вързан към интернет.
 
@random_oracle, вкарваш го прекалено на дълбоко :)
@nasibg, защо не искаш да ползваш PDO?
@t0m3kk, най-сигурно е изобщо да забрани достъпа до config.php за всички с htaccess.
 
@bancov96 Кое му е дълбокото? Това със SSL сертификата е готово.
@nasibg, защо не искаш да ползваш PDO? - Защото за сега пиша олд скул.

А и във lock.php не трябва ли да има mysql_real_escape_string?
<?php
define('IN_VALID', true);
include("config.php");
session_start();
$user_check=mysql_real_escape_string($_SESSION['login_user']);

$ses_sql=mysql_query("select username from admin where username='$user_check' ");

$row=mysql_fetch_array($ses_sql);

$login_session=$row['username'];

if(!isset($login_session))
{
header("Location: index.php");
}
?>

Според вас как е кода? сигурен ли е? чакам още някой(със код(допълнение)) да ми даде съвет.Наистина кода искам да го подобря и подсигуря. Сигурен ли е кода, може ли да се разчита на него? При по сериозни бг проекти как е този логин скрипт? има ли по сигурни? Аз просто искам да съм сигурен че напълно може да разчитам на кода.
 
Няма регистрация, само авторизиращата система. Регистрацията е лесна а и знам как да я направя. Въпроса е секюритито на авторизиращата система...

<?php
include("config.php");
session_start();
if($_SERVER["REQUEST_METHOD"] == "POST")
{
$myusername=addslashes($_POST['username']);
$mypassword=addslashes($_POST['password']);
$sql="SELECT id FROM admin WHERE username='$myusername' and passcode='$mypassword'";
$result=mysql_query($sql);
$row=mysql_fetch_array($result);
$active=$row['active'];
$count=mysql_num_rows($result);
if($count==1)
{
session_register("myusername");
$_SESSION['login_user']=$myusername;
header("location: welcome.php");
}
else
{
$error="Грешно име или парола";
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Вход</title>
</head>
<body>
<div align="center">
<div>
<div><b>Администрация</b></div>
<div><?php
$username=$_SESSION['login_user'];
if($username==NULL)
{
echo'
<form method="post">
<label>Име: </label><input type="text" name="username"/><br /><br />
<label>Парола: </label><input type="password" name="password" /><br/><br />
<input type="submit" value="Влез"/><br />
</form>';
}
else
{
//echo"Добре дошъл $username.";

header('Location: welcome.php');

// показва(след като съм се логнал и отида на index.php) ми warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\index.php:39) in C:\xampp\htdocs\index.php on line 59

}
?>
<?php echo $error; ?>
</div>
</div>
</div>
</body>
</html>
 
nasibg каза:
@bancov96 Кое му е дълбокото? Това със SSL сертификата е готово.

Ставаше въпрос за това, че ти говори за authority и bruteforce атаки.
 
Някой може ли да помогне за проблема със хейдъра? Относно темата, ако до утре никой не помогне давам точката на t0m3kk.
 
Това което е написал t0m3kk е задължителното и то ще те предпази от basic хакери но има много начини за хакване и това няма да те предпази напълно. Например за хсс атаки съм чел че използват еквивалент на специалните символи например < става %3c и по този начин преодоляват htmlspecialchars както и много други начини. Преодоляват дори md5. Аз например използвам това което е по уроци от туриста с някои добавки от мене и md5 за паролата но ако решат да те хакнат и експерт по сигурността да си пак ще те хакнат.

<?php
$queryString = strtolower($_SERVER['QUERY_STRING']);

if (strstr($queryString,"<") OR strstr($queryString,"%3c") OR strstr($queryString,">") OR strstr($queryString,"%3e")
OR strstr($queryString,"(") OR strstr($queryString,"%28") OR strstr($queryString,")") OR strstr($queryString,"%29")
OR strstr($queryString,"..") OR strstr($queryString,",") OR strstr($queryString,"--") OR strstr($queryString,"*")
OR strstr($queryString,"++") OR strstr($queryString,"!") OR strstr($queryString,"%21") OR strstr($queryString,"@")
OR strstr($queryString,"'") OR strstr($queryString,"%27") OR strstr($queryString,"#") OR strstr($queryString,"%23")
OR strstr($queryString,"`") OR strstr($queryString,"%60") OR strstr($queryString,"~") OR strstr($queryString,"%7e")
OR strstr($queryString,"^") OR strstr($queryString,"%5e") OR strstr($queryString,"%2b%2b") OR strstr($queryString,"1%3d1")
OR strstr($queryString,"a%3da") OR strstr($queryString,"select")) {

$loc = $_SERVER['PHP_SELF'];
$ip = $_SERVER['REMOTE_ADDR'];
$date = date ("d-m-Y @ h:i:s");
$lfh = "log.txt";
$log = fopen ( $lfh,"a+" );
fputs ($log, "Attack Date: $date | Attacker IP: $ip | QueryString: $loc?=$queryString\n");
fclose($log);

echo "Вашата атака беше записана!"; exit;
}

function addslashes_to_array($a) {

if (!is_array($a)) return addslashes($a);



foreach($a as $key => $val)

$a[$key] = addslashes_to_array($val);

return ($a);

}

addslashes_to_array(&$_POST);

addslashes_to_array(&$_GET);

function htmlspecialchars_to_array($b) {

if (!is_array($b)) return htmlspecialchars($b);



foreach($b as $key => $val1)

$b[$key] = htmlspecialchars_to_array($val1);

return ($b);

}

htmlspecialchars_to_array(&$_POST);

htmlspecialchars_to_array(&$_GET);

?>

Успех в начинанието :)
 
@teroristd, би ли ми казал какво означава да преодоляват md5? :lol:
@nasibg, най-добре забрани всички знаци, освен букви,цифри и тирета за потребителски имена. На всичко майката му е филтриране на входящата информация и ... prepared statements срещу SQL Injection. :)
 
bancov96 означава че разкодират парола мината през md5 мога и пример да ти дам но не искам че ще изтрият темата или коментара.
 
Това, че има сайтове, в които се добавят оригинален низ към md5 хеш (нещо като база с хешове) и можеш случайно да намериш твоят хеш и да видиш оригиналния не означава, че можеш да разбиеш md5 хеш.
 
не е само по този начин има и програми които го разбиват но както и да е не искам да споря :wink:
 
Аре да ви дам една забавна оффтопик занимавка.

Възможно ли е според вас MD5 сумата на някое съобщение да е нулево, демек само нулеви байтове :)
 
И да е възможно, отново ще имаш хеш, но и 128 битов да е, ще се разкодира много лесно, особенно ако се почва от 0
 
Въпросът е дали е възможно :)

Но няма да се "разкодира" лесно при положение че е само нули, ще се чупи точно толкова лесно, колкото и всички останали съобщения, даващи някаква хеш сума.
 

Back
Горе