Само в интерес на главата (така че ще имате представа защо Fred -ii- каза да не използвам този код) - ще разглобя донякъде това, по ред, докато го минавам (не е лично копаене на човека, който задава въпроса - но само за да дам представа, че опитът да се изгради наполовина сигурно приложение върху стека LAMP изисква малко внимание и преднамереност... и кървав цинизъм, съчетан с допускането на най-лошото в човечеството помага):
Точка 1
Не е голямо - но наистина, ако ще започнете сесия, трябва да започнете сесия, независимо дали има $_POST
данни или не. Вероятно трябва да изискате своя конфигурационен файл и да започнете сесията отгоре преди всичко друго.
Не е терминална грешка (тъй като нямате валидиране на сесията) - просто странно.
Точка 2
Имате изход в този файл (echo
) следователно трябва да е под корена на документа и да е наличен в уеб дървото.
include("config.php");
Това наистина не е написано правилно, вероятно трябва да бъде require_once 'config.php';
(ако приемем, че това е задължителен програмен файл, а не незадължително включване, което може да бъде позволено да се провали), но това е не грешката. Грешката е, че имате своя конфигурационен файл в корена на документа. Грешна конфигурация на сървъра или проста печатна грешка в този файл теоретично могат да позволят съдържанието на този файл да бъде изведено на екрана в обикновен текст, потенциално разкривайки низовете за връзка с вашата база данни (и кой знае какво още) към world + dog.
Конфигурационните файлове трябва да съществуват извън уеб дървото или, в противен случай, в директория, защитена с нещо като .htaccess
Deny from all
. Те никога не трябва да са достъпни през HTTP.
Точка 3
mysql
библиотеката е остаряла и изобщо не трябва да се използва; MySQLi или PDO са правилният начин, в идеалния случай с обвързани параметри/стойности:
Лично аз имах за PDO.
Точки 4 и 5
$password = mysql_real_escape_string(stripslashes(md5($_POST['password'])));
Първо, редът на това е грешен. Хеширате $_POST['password']
итогава опит за премахване на наклонени черти - няма да има никакви наклонени черти, след като бъде хеширана. Ако обаче се опитвате да попречите на хората да използват наклонени черти (или каквото и да е) в паролите, трябва да ги премахнете, преди да хеширате низа.
Следващ md5
не трябва да се използва като алгоритъм за хеширане на пароли, установено е, че е слаб и може да бъде грубо принуден да създава сблъсъци на низове много по-често, отколкото би трябвало.
Да, виетрябвате съхранявайте само хешове или "пръстови отпечатъци" на паролите, а не самите пароли, но в идеалния случай искате да солите и хеширате (с поне sha1
) тези пароли, а не просто да ги хвърлят в md5()
функция.
Вижте:http://uk3.php.net/mcrypt например
И направете търсене на „хеширане на пасиране на парола“ с помощта на избраната от вас търсачка.
Точка 6
SELECT id FROM $table
WHERE username = '" . $username . "'
and password = '" . $password . "';
Добавих в =
това липсваше в оригиналния въпрос, но все пак не съвпадат по потребителско име и парола във вашата заявка ... ако някой успее да получи SQL инжекция във вашето потребителско име, паролата никога няма да бъде проверена. Представете си:
SELECT user.id
FROM user WHERE user.username = 'fred' OR 1 = 1
-- AND user.password = 'abc123'
По-добре е да изберете пръстовия отпечатък на потребителския идентификатор и парола от базата данни и след това да оцените паролата в приложението, вместо да се доверите на проверка на парола в слоя на базата данни. Това също означава, че можете да използвате специален алгоритъм за хеширане и осоляване в самото приложение, за да потвърдите паролите си.
Точка 7
$_SESSION['user'] = $_POST["username"];
Това е просто съхраняване на потребителското име в сесията? Това по никакъв начин не трябва да се използва като „проверител на влизане“, особено тъй като във вашата сесия (очевидно) няма нищо, което да предотврати отвличане .
Идентификационният номер на сесията може лесно да бъде подушен от бисквитката на сесия на живо и това е всичко, което би било необходимо, за да се „заеме“ нечие друго влизане. Трябва поне да се опитате да намалите вероятността сесията да бъде отвлечена чрез свързване на IP адреса на потребителя, низа на UserAgent или някаква друга комбинация от относително статични данни, с които можете да сравнявате на всяка страница... практически всеки подход има недостатъци. (особено, както открих, ако имате посетители, използващи AOL) - но можете да направите вероятно 99+% ефективен пръстов отпечатък на сесията, за да смекчите отвличането с много малък шанс сесията на потребителя да бъде изхвърлена по погрешка.
В идеалния случай може да искате да създадете токен за сесията, за да смекчите CSRF атаки, когато потребителят трябва да извърши "привилегировано" действие върху базата данни (актуализира своите данни или каквото и да е). Токенът може да бъде напълно произволен и уникален код, съхранен в базата данни и/или в SSL бисквитка, когато потребителят влезе (ако приемем, че потребителят не може да извърши каквото и да е действие, което актуализира базата данни извън HTTPS, тъй като това просто ще предаде данните в ясен текст в интернет – което би било лоша идея ).
Токенът се поставя в скрито поле на формуляр за всички/всички формуляри и се проверява спрямо стойността, съхранена в бисквитката (или сесията или базата данни), когато този формуляр бъде изпратен. Това гарантира, че лицето, което изпраща формуляра, има поне сесия на живо във вашия уебсайт.