Захист ідентифікатора сесій у PHP. Підводне каміння використання сесій у PHP Передача значення або масиву за допомогою сесії PHP

Вітаю, шановне співтовариство.

Насамперед хочу подякувати за дуже корисний ресурс. Не раз знаходив тут безліч цікавих ідей та практичних порад.

Мета цієї статті - висвітлити підводні камені використання сесій у PHP. Звичайно, є документація з PHP і безліч прикладів, і ця стаття не претендує на повне керівництво. Вона покликана розкрити деякі нюанси роботи із сесіями та убезпечити розробників від непотрібної витрати часу.

Найпоширенішим прикладом використання сесій є, звісно, ​​авторизація користувачів. Почнемо з самої базової реалізації, щоб послідовно розвивати її з появою нових завдань.

(З метою економії місця та часу обмежимося в прикладах лише самими функціями роботи з сесіями, замість того, щоб будувати тут повноцінний тестовий додаток з гарною ієрархією класів, вичерпною обробкою помилок та іншими правильними штуками).

Function startSession() ( // Якщо сесія вже була запущена, припиняємо виконання та повертаємо TRUE // (параметр session.auto_start у файлі налаштувань php.ini має бути вимкнений - значення за замовчуванням) if (session_id()) return true; else return session_start(); // Примітка: До версії 5.3.0 функція session_start() повертала TRUE навіть у разі помилки.// Якщо ви використовуєте версію нижче 5.3.0, виконуйте додаткову перевірку session_id() // після виклику session_start() ) function destroySession() ( if (session_id()) ( // Якщо є активна сесія, видаляємо куки сесії, setcookie(session_name(), session_id(), time()-60*60*24); // і знищуємо сесію session_unset( ); session_destroy(); ) )

Примітка: Маємо на увазі, що базові знання про сесія PHP у читача є, тому принцип роботи функцій session_start() і session_destroy() висвітлювати тут не будемо. Завдання верстки форми входу та автентифікації користувача не належать до теми статті, тому їх ми також опустимо. Нагадаю лише, що для ідентифікації користувача в кожному наступному запиті нам необхідно в момент успішного входу зберегти в сесійній змінній (з ім'ям userid, наприклад) ідентифікатор користувача, який буде доступний у всіх наступних запитах у межах життя сесії. Також потрібно реалізувати обробку результату нашої функції startSession(). Якщо функція повернула FALSE – відобразити у браузері форму входу. Якщо функція повернула TRUE, і сесійна змінна, що містить ідентифікатор авторизованого користувача (у нашому випадку – userid), існує – відобразити сторінку авторизованого користувача (докладніше про обробку помилок див. додаток від 2013-06-07 у розділі сесійних змінних).

Поки що все зрозуміло. Запитання розпочинаються, коли потрібно реалізувати контроль відсутності активності користувача (session timeout), дати можливість одночасної роботи в одному браузері кількох користувачів, а також захистити сесії від несанкціонованого використання. Про це й йтиметься нижче.

Контроль відсутності активності користувача вбудованими засобами PHP Перше питання, яке часто виникає у розробників різноманітних консолей для користувачів - автоматичне завершення сеансу у разі відсутності активності з боку користувача. Немає нічого простішого, ніж зробити це за допомогою вбудованих можливостей PHP. (Цей варіант не відрізняється особливою надійністю та гнучкістю, але розглянемо його для повноти картини).

Function startSession() ( // Таймаут відсутності активності користувача (у секундах) $sessionLifetime = 300; if (session_id()) return true; // Встановлюємо час життя куки ini_set("session.cookie_lifetime", $sessionLifetime); // Якщо таймів відсутності активності користувача заданий, встановлюємо час життя сесії на сервері // Примітка: Для production-сервера рекомендується встановити ці параметри у файлі php.ini if ​​($sessionLifetime) ini_set("session.gc_maxlifetime", $sessionLifetime); if (ses )) ( setcookie(session_name(), session_id(), time()+$sessionLifetime); return true; ) else return false; )

Небагато пояснень. Як відомо, PHP визначає, яку саме сесію потрібно запустити, на ім'я куки, що передається браузером в заголовку запиту. Браузер, у свою чергу, отримує цей куки від сервера, куди поміщає його функція session_start(). Якщо час життя кукі в браузері минув, він не буде переданий у запиті, а значить PHP не зможе визначити, яку сесію потрібно запустити, і розцінить це як створення нової сесії. Параметр налаштувань PHP session.gc_maxlifetime, який встановлюється рівним нашому таймууту відсутності активності користувача, задає час життя PHP-сесії та контролюється сервером. Працює контроль часу життя сесії в такий спосіб (тут розглядається приклад сховища сесій у часових файлах як найпоширеніший і встановлений за замовчуванням у PHP варіант).

У момент створення нової сесії в каталозі, встановленому як каталог зберігання сесій у параметрі налаштувань PHP session.save_path, створюється файл з ім'ям sess_, де - ідентифікатор сесії. Далі, у кожному запиті, у момент запуску вже існуючої сесії, PHP оновлює час модифікації файлу. Таким чином, у кожному наступному запиті PHP, шляхом різниці між поточним часом і часом останньої модифікації сесії, може визначити, чи є сесія активною, чи її час життя вже минув. (Механізм видалення старих файлів сесій докладніше розглядається у наступному розділі).

Примітка: Тут слід зазначити, що параметр session.gc_maxlifetime діє на всі сесії в межах одного сервера (точніше, в межах головного процесу PHP). На практиці це означає, що якщо на сервері працює кілька сайтів, і кожен з них має власний тайм відсутності активності користувачів, то встановлення цього параметра на одному з сайтів призведе до його встановлення і для інших сайтів. Те саме стосується і shared-хостингу. Щоб уникнути подібної ситуації, використовуються окремі каталоги сесій для кожного сайту в межах одного сервера. Встановлення шляху до каталогу сесій здійснюється за допомогою параметра session.save_path у файлі налаштувань php.ini, або за допомогою функції ini_set(). Після цього сесії кожного сайту зберігатимуться в окремих каталогах, і параметр session.gc_maxlifetime, встановлений на одному із сайтів, діятиме лише на його сесії. Ми не будемо розглядати цей випадок докладно, тим більше, що в нас є більш гнучкий варіант контролю відсутності активності користувача.

Контроль відсутності активності користувача за допомогою сесійних змінних Здавалося б, попередній варіант за всієї своєї простоти (всього пару додаткових рядків коду) дає все, що нам потрібно. Але що якщо не кожен запит можна розцінювати як результат активності користувача? Наприклад, на сторінці встановлено таймер, який періодично виконує запит AJAX на отримання оновлень від сервера. Такий запит не можна розцінювати як активність користувача, а значить, автоматичне продовження часу життя сесії є не коректним у даному випадку. Але ми знаємо, що PHP оновлює час модифікації файлу сесії автоматично при кожному виклику функції session_start(), а значить будь-який запит призведе до продовження часу життя сесії, і тайм відсутності активності користувача не настане ніколи. До того ж, остання примітка з попереднього розділу про тонкощі роботи параметра session.gc_maxlifetime може здатися комусь надто заплутаною та складною у реалізації.

Для вирішення цієї проблеми відмовимося від використання вбудованих механізмів PHP та введемо декілька нових сесійних змінних, які дозволять нам контролювати час відсутності активності користувачів самостійно.

Function startSession($isUserActivity=true) ( ​​$sessionLifetime = 300; if (session_id()) return true; // Встановлюємо час життя куки до закриття браузера (контролювати все будемо на стороні сервера) ini_set("session.cookie_lifetime", if (!session_start()) return false; , коли була оновлена ​​сесійна змінна lastactivity) if (isset($_SESSION["lastactivity"]) && $t-$_SESSION["lastactivity"] >= $sessionLifetime) ( // Якщо час, що минув з моменту останньої активності користувача, / / більше тайму відсутності активності, значить сесія закінчилася, і потрібно завершити сеанс destroySession(); часу, // продовжуючи цим час сеансу ще на sessionLifetime секунд if ($isUserActivity) $_SESSION["lastactivity"] = $t; ) ) return true; )

Підсумуємо. У кожному запиті ми перевіряємо, чи не досягнуть таймату з моменту останньої активності користувача до поточного моменту, і якщо він досягнений - знищуємо сесію та перериваємо виконання функції, повертаючи FALSE. Якщо ж таймати не досягнуто, і в функцію передано параметр $isUserActivity зі значенням TRUE - оновлюємо час останньої активності користувача. Все, що нам залишається зробити - це визначати в скрипті, чи є запит результатом активності користувача, і якщо ні - викликати функцію startSession зі значенням параметра $isUserActivity, рівним FALSE.

Додаток від 2013-06-07 Обробка результату функції sessionStart()

У коментарях звернули увагу, що повернення FALSE не дає повного розуміння причини помилки, і це абсолютно справедливо. Я не став публікувати докладну обробку помилок (обсяг статті і так не маленький), оскільки це не стосується прямо до теми статті. Але з огляду на коментарі внесу ясність.

Як видно, функція sessionStart може повернути FALSE у двох випадках. Або сесію не вдалося запустити через якісь внутрішні помилки сервера (наприклад, неправильні налаштування сесій у php.ini), або час життя сесії минув. У першому випадку ми повинні перекинути користувача на сторінку з помилкою про те, що є проблеми на сервері, та формою звернення до служби підтримки. У другому випадку ми повинні перевести користувача на форму входу та вивести в ній відповідне повідомлення про те, що час сесії минув. Для цього нам необхідно ввести коди помилок і повертати замість FALSE відповідний код, а в методі, що викликає, перевіряти його і діяти відповідним чином.

Тепер, навіть якщо сесія на сервері, як і раніше, існує, вона буде знищена при першому ж зверненні до неї, якщо таймуть відсутності активності користувача минув. І це станеться незалежно від того, який час життя сесій встановлений у глобальних налаштуваннях PHP.

Примітка: А що станеться, якщо браузер був закритий, і кукі з ім'ям сесії автоматично знищили? Запит до сервера при наступному відкритті браузера не міститиме кукі сесії, і сервер не зможе відкрити сесію і перевірити тайм відсутності активності користувача. Для нас це рівнозначно створенню нової сесії і ніяк не впливає на функціонал та безпеку. Але виникає справедливе питання - а хто ж тоді знищить стару сесію, якщо досі її знищували ми після таймууту? Чи вона тепер висітиме в каталозі сесій вічно? Для очищення старих сесій у PHP існує механізм під назвою garbage collection. Він запускається в момент чергового запиту до сервера та чистить усі старі сесії на підставі дати останньої зміни файлів сесій. Але запуск механізму garbage collection відбувається при кожному запиті до серверу. Частота (а точніше, ймовірність) запуску визначається двома параметрами налаштувань session.gc_probability та session.gc_divisor. Результат від поділу першого параметра на другий і є ймовірністю запуску механізму garbage collection. Таким чином, для того, щоб механізм очищення сесій запускався при кожному запиті до сівер, ці параметри потрібно встановити в рівні значення, наприклад «1». Такий підхід гарантує чистоту каталогу сесій, але, очевидно, надто накладний для сервера. Тому в production-системах за умовчанням встановлюється значення session.gc_divisor, що дорівнює 1000, що означає, що механізм garbage collection запускатиметься з ймовірністю 1/1000. Якщо ви поекспериментуєте з цими налаштуваннями у своєму файлі php.ini, то зможете помітити, що в описаному вище випадку, коли браузер закривається та очищає всі свої куки, в каталозі сесій якийсь час все ще залишаються старі сесії. Але це повинно вас хвилювати, т.к. як уже було сказано, це жодним чином не впливає на безпеку нашого механізму.

Додаток від 2013-06-07 Запобігання зависанню скриптів через блокування файлу сесії

У коментарях порушили питання про зависання скриптів, що одночасно виконуються, через блокування файлу сесії (як найяскравіший варіант - long poll).

Для початку зазначу, що ця проблема безпосередньо не залежить від завантаженості сервера чи кількості користувачів. Звісно, ​​що більше запитів, то повільніше виконуються скрипти. Але це непряма залежність. Проблема виникає лише у межах однієї сесії, коли серверу надходить кілька запитів від імені користувача (наприклад, одне із них long poll, інші - звичайні запити). Кожен запит намагається отримати доступ до того самого файлу сесії, і якщо попередній запит не розблокував файл, то наступний висітиме в очікуванні.

Для блокування файлів сесій до мінімуму настійно рекомендується закривати сесію шляхом виклику функції session_write_close() відразу після того, як виконані всі дії із сесійними змінними. Насправді це означає, що слід зберігати в сесійних змінних все поспіль і звертатися до них протягом виконання скрипта. А якщо і треба зберігати в сесійних змінних якісь робочі дані, то зчитувати їх відразу при старті сесії, зберігати в локальні змінні для подальшого використання і закривати сесію (мається на увазі закриття сесії за допомогою функції session_write_close, а не знищення за допомогою session_des

У нашому прикладі це означає, що відразу після відкриття сесії, перевірки часу її життя та існування авторизованого користувача, ми повинні рахувати та зберегти всі додаткові необхідні додатку сесійні змінні (якщо такі існують), після чого закрити сесію за допомогою виклику session_write_close() та продовжити виконання скрипту, чи то long poll, чи звичайний запит.

Захист сесій від несанкціонованого використання Уявімо собі ситуацію. Один з ваших користувачів чіпляє троян, який грабує кукі браузера (у якому зберігається наша сесія) та відправляє його на вказаний email. Зловмисник отримує куки та використовує його для підробки запиту від імені нашого авторизованого користувача. Сервер успішно приймає та обробляє цей запит, якби він прийшов від авторизованого користувача. Якщо не реалізовано додаткову перевірку IP-адреси, така атака призведе до успішного злому облікового запису користувача з усіма наслідками.

Чому це стало можливим? Очевидно, тому що ім'я та ідентифікатор сесії завжди одні й самі на весь час життя сесії, і якщо отримати ці дані, то можна безперешкодно надсилати запити від імені іншого користувача (природно, в межах часу життя цієї сесії). Можливо, це не найпоширеніший вид атак, але все теоретично виглядає цілком реалізованим, особливо враховуючи, що подібному трояну навіть не потрібні права адміністратора, щоб грабувати куки браузера користувача.

Як же можна захиститися від подібних атак? Знов-таки, очевидно, обмеживши час життя ідентифікатора сесії та періодично змінюючи ідентифікатор у межах однієї сесії. Ми можемо також змінювати ім'я сесії, повністю видаляючи стару і створюючи нову сесію, копіюючи в неї всі сесійні змінні зі старої. Але на суть підходу це не впливає, тому для простоти обмежимося лише ідентифікатором сесії.

Зрозуміло, що чим менше часу життя ідентифікатора сесії, тим менше часу у зловмисника, щоб отримати і застосувати куки для підробки запиту користувача. В ідеальному випадку для кожного запиту має використовуватися новий ідентифікатор, що дозволить мінімізувати можливість використання чужої сесії. Але ми розглянемо загальний випадок коли час регенерації ідентифікатора сесії встановлюється довільно.

(Опустимо ту частину коду, що вже розглянута).

Function startSession($isUserActivity=true) ( ​​// Час життя ідентифікатора сесії $idLifetime = 60; ... if ($idLifetime) ( // Якщо час життя ідентифікатора сесії задано, // перевіряємо час, що минув з моменту створення сесії або останньої) регенерації // (час останнього запиту, коли було оновлено сесійну змінну starttime) if (isset($_SESSION["starttime"])) ( if ($t-$_SESSION["starttime"] >= $idLifetime) ( // Час життя ідентифікатора сесії закінчилося // Генеруємо новий ідентифікатор session_regenerate_id(true); $_SESSION["starttime"] = $t; $_SESSION["starttime"] = $t; ) ) return true; )

Отже, при створенні нової сесії (що відбувається в момент успішного входу користувача), ми встановлюємо сесійну змінну starttime, що зберігає для нас час останньої генерації ідентифікатора сесії, значення, що дорівнює поточному часу сервера. Далі в кожному запиті ми перевіряємо, чи достатньо часу (idLifetime) не пройшло з моменту останньої генерації ідентифікатора, і якщо пройшло - генеруємо новий. Таким чином, якщо протягом встановленого часу життя ідентифікатора зловмисник, який отримав куки авторизованого користувача, не встигне ним скористатися, підроблений запит буде розцінений сервером як неавторизований і зловмисник потрапить на сторінку входу.

Примітка: Новий ідентифікатор сесії потрапляє в cookie браузера при виклику функції session_regenerate_id(), яка надсилає новий cookie, аналогічно функції session_start(), тому нам немає необхідності оновлювати cookie самостійно.

Якщо ми хочемо максимально убезпечити наші сесії, достатньо встановити час життя ідентифікатора в одиницю або взагалі винести функцію session_regenerate_id() за дужки і прибрати всі перевірки, що призведе до регенерації ідентифікатора в кожному запиті. (Я не перевіряв вплив такого підходу на швидкодію і можу тільки сказати, що функція session_regenerate_id(true) виконує по суті всього 4 дії: генерація нового ідентифікатора, створення заголовка з куки сесії, видалення старого та створення нового файлу сесії).

Ліричний відступ: Якщо троян виявиться настільки розумним, що не буде відправляти куки зловмиснику, а сам організує відправку заздалегідь підготовленого підробленого запиту відразу при отриманні куки, описаний вище метод, швидше за все, не зможе захистити від подібної атаки, тому що між часом отримання трояном кукі і надсиланням підробленого запиту практично не буде різниці, і велика ймовірність, що в цей момент не відбудеться регенерації ідентифікатора сесії.

Можливість одночасної роботи в одному браузері від імені кількох користувачів Остання задача, яку хотілося б розглянути, - можливість одночасної роботи в одному браузері кількох користувачів. Ця можливість особливо корисна на етапі тестування, коли потрібно емулювати одночасно роботу користувачів, і бажано робити це у своєму улюбленому браузері, а не використовувати весь доступний арсенал або відкривати кілька екземплярів браузера в режимі «інкогніто».

У попередніх прикладах ми не задавали явно ім'я сесії, тому використовувалося ім'я, встановлене в PHP за замовчуванням (PHPSESSID). Це означає, що всі сесії, які ми створювали досі, відправляли браузеру куки під ім'ям PHPSESSID. Очевидно, якщо ім'я куки завжди однакове, то немає можливості в межах одного браузера організувати дві сесії з однаковим ім'ям. Але якби ми для кожного користувача використовували власне ім'я сесії, то проблему вирішили б. Так і зробимо.

Function startSession($isUserActivity=true, $prefix=null) ( ... if (session_id()) return true; // Якщо в параметрах передано префікс користувача, // встановлюємо унікальне ім'я сесії, що включає цей префікс, // інакше встановлюємо загальне для всіх користувачів ім'я (наприклад, MYPROJECT) session_name("MYPROJECT".($prefix ? "_".$prefix: "")); ini_set("session.cookie_lifetime", 0); if (! session_start()) return false; ... )

Тепер залишилося подбати про те, щоб скрипт, що викликає, передавав у функцію startSession() унікальний префікс для кожного користувача. Це можна зробити, наприклад, через передачу префікса в GET/POST параметрах кожного запиту або через додаткові куки.

Висновок На закінчення наведу повний кінцевий код наших функцій для роботи з сесіями PHP, що включає всі розглянуті вище завдання.

Function startSession($isUserActivity=true, $prefix=null) ( $sessionLifetime = 300; $idLifetime = 60; if (session_id()) return true; session_name("MYPROJECT".($prefix ? "_".$prefix: "")); ini_set("session.cookie_lifetime", 0); if (! session_start()) return false; ) && $t-$_SESSION["lastactivity"] >= $sessionLifetime) ( destroySession(); return false; ) else ( if ($isUserActivity) $_SESSION["lastactivity"] = $t; ) ) if ($idLifetime ) ( if (isset($_SESSION["starttime"])) ( if ($t-$_SESSION["starttime"] >= $idLifetime) ( session_regenerate_id(true); $_SESSION["starttime"] = $t; ) ) else ( $_SESSION["starttime"] = $t; ) ) return true; ) function destroySession() ( if (session_id()) ( session_unset(); setcookie(session_name(), session_id(), time() -60*60*24);session_destroy(); ) )

Сподіваюся, ця стаття заощадить трохи часу тим, хто ніколи особливо не заглиблювався в механізм сесій, і дасть достатньо розуміння цього механізму тим, хто починає знайомитися з PHP.

Вам потрібне ім'я користувача та пароль?

Для надсилання статей через Інтернет та перевірки статусу надісланих статей вам необхідно зареєструватися та увійти в систему під своїм обліковим записом.

Контрольний список підготовки статті до відправлення

Як один із етапів процесу відправлення статті автори повинні перевірити відповідність їх статті всім наступним пунктам, статті можуть бути повернені авторам, якщо вони не відповідають цим вимогам.

Стаття підготовлена ​​відповідно до вимог

Умови передачі авторських прав

Автори зберігають за собою авторські права на роботу і передають журналу право першої публікації разом з роботою, одночасно ліцензуючи її на умовах Creative Commons Attribution License, яка дозволяє іншим поширювати цю роботу з обов'язковим зазначенням авторства цієї роботи та посиланням на оригінальну публікацію в цьому журналі.

Заява про конфіденційність

Імена та адреси електронної пошти, введені на сайті цього журналу, будуть використані виключно для цілей, зазначених цим журналом, і не будуть використані для будь-яких інших цілей або надані іншим особам та організаціям.

Перед реєстрацією в системі користувач погоджується з політикою обробки та зберігання персональних даних.

Платежі автора

1500 знаків із пробілами: 300,00 (RUB)

Публікація 1 сторінка рукопису (1500 знаків) – 300 рублів. Графічні матеріали / таблиці оплачуються окремо – 50 рублів / 1 шт. Авторський екземпляр включаючи пересилання по Росії оплачується за бажанням автора - 400 рублів. Пересилання за кордон – 800 рублів. Вартість пересилання довідки про прийняття матеріалу до публікації – 150 руб.

Переклад супровідної інформації (ПІБ, місце роботи авторів; назва; анотація; ключові слова) англійською мовою 0,5 рублів за кожен знак, включаючи пробіли.

Увага! Автори (кандидати та доктори наук), що мають за даними elibrary.ru 300 і більше цитувань (при цьому частка самоцитувань має бути не більше 30%), публікуються безкоштовно. Якщо Ви маєте право на безкоштовну публікацію, під час надсилання матеріалу в поле коментарі вкажіть посилання на Ваш профіль в elibrary з кількістю цитувань. Витрати на пересилання збірника оплачуються окремо.

Безпека веб-сайтів ґрунтується на управлінні сесіями. Коли користувач підключається до безпечного сайту, він надає облікові дані, як правило, у формі імені користувача та пароля. Веб-сервер не має уявлення про те, який користувач уже увійшов до системи та як він переходить від сторінки до сторінки. Механізм сесій дозволяє користувачам не вводити пароль щоразу, коли вони хочуть виконати нову дію або перейти до нової сторінки.

По суті управління сесією гарантує, що в даний час з'єднаний той користувач, який проходив авторизацію. Але, на жаль, сесії стали очевидною мішенню для хакерів, оскільки вони можуть дозволити отримати доступ до веб-сервера без необхідності автентифікації.

Після автентифікації користувача веб-сервер надає йому ідентифікатор сесії. Цей ідентифікатор зберігається в браузері і підставляється щоразу, коли потрібна автентифікація. Це дозволяє уникнути повторюваних процесів введення логіну/паролю. Все це відбувається у фоновому режимі та не завдає дискомфорту користувачеві. Уявіть, якби ви вводили ім'я та пароль щоразу, коли переглядали нову сторінку!

У цій статті я постараюся викласти всі відомі мені способи захисту сесії ідентифікатора в PHP.

Використання cookie За промовчанням вся інформація про сесію, включаючи ID, передається до cookie. Але так не завжди. Деякі користувачі відключають cookie у своїх браузерах. У такому випадку браузер передаватиме ідентифікатор сесії в URL.

Тут ID передається у відкритому вигляді, на відміну від сесії через cookie, коли інформація прихована в заголовку HTTP. Найпростішим способом захисту від цього буде заборона передачі ідентифікатора сесії через адресний рядок. Зробити це можна, прописавши наступне конфігураційний файл Apache-сервера.htaccess:

Php_flag session.use_only_cookies on

Використання шифрування Якщо на вашому сайті має бути оброблена конфіденційна інформація, така як номери кредитних карт (привіт від Sony), слід використовувати SSL3.0 або TSL1.0 шифрування. Для цього під час встановлення cookie слід вказувати true для параметра secure.

Якщо ви зберігаєте пароль сесії в змінній $_SESSION (все-таки краще використовувати SQL), то не варто зберігати його у відкритому вигляді.

If ($_SESSION["password"] == $userpass) ( // код )

Наведений вище код не є безпечним, оскільки пароль зберігається у вигляді звичайного тексту в змінній сесії. Натомість використовуйте md5-шифрування, приблизно так:

If ($_SESSION["md5password"] == md5($userpass)) ( // код )

Перевірка браузера Щоб відсікти можливість використання сесії з іншого браузера (комп'ютера), слід ввести перевірку поля HTTP-заголовка user-agent:

Session_start(); if (isset($_SESSION["HTTP_USER_AGENT"])) ( if ($_SESSION["HTTP_USER_AGENT"] != md5($_SERVER["HTTP_USER_AGENT"])) ( // код ) ) else ( $_SESSION["HTTP_USER_AGENT" ] = md5($_SERVER["HTTP_USER_AGENT"]); )

Термін дії сесії Обмежте час життя сесії та час дії cookie. За промовчанням термін дії сесії 1440 секунд. Змінити це значення можна через php.ini та.htaccess. Приклад для.htaccess:

# Час життя сесії за секунди
php_value session.gc_maxlifetime 3600
# Час життя кукі в секундах
php_value session.cookie_lifetime 3600

Прив'язка IP-адреси У певних ситуаціях (не завжди) слід встановити прив'язку IP-адреси. В основному, коли кількість користувачів обмежена і мають статичні IP. Перевірка може бути або за списком дозволених IP-адрес,

Include ("ip_list.php"); //$ip_white_list = array ("admin1" => "111.222.333.444", "admin2" => "555.666.777.888"); if(!empty(array_search($_SERVER["REMOTE_ADDR"],$ip_white_list))) ( header("Location: admin.php"); ) else ( echo "ACCESS DENY!"; )

Або за IP-адресою для кожного запиту (лише для статичних IP):

If(isset($_SESSION["ip"]) and $_SESSION["ip"] == $_SERVER["REMOTE_ADDR"]) ( header("Location: admin.php"); ) else ( session_unset(); $ _SESSION["ip"] = $_SERVER["REMOTE_ADDR"]; )

Слід усвідомлювати, що уникнути взлому неможливо. Можна тільки максимально ускладнити цей злам будь-якими відомими способами. Однак слід також не забувати про своїх легальних користувачів, щоб не ускладнити їм життя таким захистом.

Цей матеріал був написаний в 2009 і залишки одного з наших найбільш популярних місць. Якщо ви збираєтеся дізнатися більше про PHP і MySQL, ви можете зрозуміти цей великий інтерес.

NOTE: Цей матеріал має бути нещодавно updated to work on PHP 4.2 or later!

Recently, я мав заощадження до роботи на малому проекті з групою людей. Він був визначений раніше на тому, що електронною поштою самий буде йти до того, щоб скоїти все в прориві, тому що я був розбитий з побудовою малого веб-сайту для проекту. Вона повинна знаходитись на simple message board, на місці, де ми можемо upload documents та інші файли для того, щоб залишити team для використання, і contact information для різних team members.

Для багатьох цих функцій до роботи, я бачу, що я потребую користувачів, які використовуються в електронній пошті, використовуючи важливу частину мережі. What I необхідно було бути в системі, що протягом літа реєстраторів для користувача ID для доступу до веб-сайту, буде безперервно використовувати цей ID без будь-якого intervention на мою частину.

У цьому матеріалі, I shall реалізується за допомогою перегляду системи I розробив, починаючи в першу половину з user signup process. У другій половині, I'll focus on site itself, як потрібні користувачі, щоб log in and then maintains, що клацнули в статуї через їх visit. I'll be paying specіal attention to the use of the session management features in PHP. Закінчити, ви повинні мати все, що ви знайдете на здійсненні подібної системи з вашого права.

Через цей матеріал, I'll може бути впевнений, що ви маєте основну familiarity з PHP language, використовуючи форми для обміну інформацією до PHP script, і як PHP може бути використаний для interact with MySQL database. Якщо будь-яке є національні концепції до вас, ви повинні почати читати мою попередньої статті, .

Part One: Символ процесу

На місцевому місці для запуску будівництва сайту, що потребує користувачів, що використовуються для реєстрації, це registration process itself. Як один буде expect, а простий Web-based form will do the trick. Here’s what it will look like:

And here’s the code for this form:




New User Registration



New User Registration Form

* indicates a required field


З objective now clear, I'll walk you через code for accesscontrol.php . За допомогою включення ваших двох handy include files: