Ochrana ID relácie v PHP. Úskalia používania relácií v PHP Odovzdávanie hodnoty alebo poľa pomocou relácie PHP

Zdravím vás, milá komunita.

V prvom rade sa vám chcem poďakovať za veľmi užitočný zdroj. Viac ako raz som tu našiel veľa zaujímavých nápadov a praktických rád.

Účelom tohto článku je poukázať na úskalia používania relácií v PHP. Samozrejme, existuje PHP dokumentácia a množstvo príkladov a tento článok nie je zamýšľaný ako kompletný návod. Je navrhnutý tak, aby odhalil niektoré nuansy práce s reláciami a chránil vývojárov pred zbytočným plytvaním časom.

Najčastejším príkladom využitia relácií je samozrejme autorizácia používateľa. Začnime s najzákladnejšou implementáciou, aby sme ju postupne rozvíjali podľa nových úloh.

(Aby sme ušetrili priestor a čas, obmedzíme naše príklady len na samotné funkcie relácie, namiesto toho, aby sme tu budovali plnohodnotnú testovaciu aplikáciu s krásnou hierarchiou tried, komplexným spracovaním chýb a ďalšími dobrými vecami).

Funkcia startSession() ( // Ak už bola relácia spustená, zastavte vykonávanie a vráťte hodnotu TRUE // (parameter session.auto_start v súbore nastavení php.ini musí byť vypnutý - predvolená hodnota) ak (session_id()) return true; else return session_start(); // Poznámka: Pred verziou 5.3.0 funkcia session_start() vracala TRUE, aj keď sa vyskytla chyba. // Ak používate verziu staršiu ako 5.3.0, vykonajte dodatočnú kontrolu for session_id() // po volaní session_start() ) funkcie cancelSession() ( if (session_id()) ( // Ak existuje aktívna relácia, vymažte cookies relácie, setcookie(session_name(), session_id(), time() )-60*60*24); // a zničíme reláciu session_unset(); session_destroy(); ) )

Poznámka: Predpokladá sa, že čitateľ má základné znalosti o reláciách PHP, preto sa tu nebudeme zaoberať princípom fungovania funkcií session_start() a session_destroy(). Úlohy rozloženia prihlasovacieho formulára a autentifikácie používateľa nesúvisia s témou článku, preto ich tiež vynecháme. Dovoľte mi pripomenúť, že na identifikáciu používateľa v každej ďalšej požiadavke musíme v momente úspešného prihlásenia uložiť identifikátor používateľa do premennej relácie (napríklad s názvom userid), ktorá bude dostupná vo všetkých nasledujúcich požiadavkách v rámci život relácie. Taktiež je potrebné implementovať spracovanie výsledku našej funkcie startSession(). Ak funkcia vráti hodnotu FALSE, zobrazte v prehliadači prihlasovací formulár. Ak funkcia vrátila hodnotu TRUE a existuje premenná relácie obsahujúca identifikátor oprávneného používateľa (v našom prípade - userid) - zobrazte stránku oprávneného používateľa (viac informácií o riešení chýb nájdete v dodatku zo dňa 2013-06- 07 v časti o premenných relácie).

Zatiaľ je všetko jasné. Otázky začínajú, keď potrebujete implementovať kontrolu nečinnosti používateľa (časový limit relácie), umožniť viacerým používateľom súčasne pracovať v jednom prehliadači a tiež chrániť relácie pred neoprávneným použitím. O tom sa bude diskutovať nižšie.

Ovládanie nečinnosti užívateľa pomocou vstavaných PHP nástrojov Prvá otázka, ktorá sa často objavuje medzi vývojármi rôznych konzol pre užívateľov, je automatické ukončenie relácie v prípade nečinnosti užívateľa. Nie je nič jednoduchšie, ako to urobiť pomocou vstavaných možností PHP. (Táto možnosť nie je obzvlášť spoľahlivá alebo flexibilná, ale pre úplnosť ju zvážime).

Funkcia startSession() ( // Časový limit nečinnosti používateľa (v sekundách) $sessionLifetime = 300; if (session_id()) vráti hodnotu true; // Nastaví životnosť súboru cookie ini_set("session.cookie_lifetime", $sessionLifetime); // Ak používateľ je nastavený časový limit nečinnosti, nastavte životnosť relácie na serveri // Poznámka: Pre produkčný server sa odporúča prednastaviť tieto parametre v súbore php.ini if ​​($sessionLifetime) ini_set("session.gc_maxlifetime", $sessionLifetime) ; if (session_start( )) ( setcookie(session_name(), session_id(), time()+$sessionLifetime); return true; ) else return false; )

Niekoľko upresnení. Ako viete, PHP určuje, ktorá relácia musí byť spustená podľa názvu súboru cookie odoslaného prehliadačom v hlavičke požiadavky. Prehliadač zase dostane tento súbor cookie zo servera, kam ho funkcia session_start() umiestni. Ak platnosť súboru cookie prehliadača vypršala, nebude odoslaný v požiadavke, čo znamená, že PHP nebude schopné určiť, ktorá relácia sa má spustiť, a bude to považovať za vytvorenie novej relácie. Parameter nastavení PHP session.gc_maxlifetime, ktorý sa rovná nášmu časovému limitu nečinnosti používateľa, nastavuje životnosť relácie PHP a je riadený serverom. Riadenie životnosti relácie funguje nasledovne (tu považujeme príklad ukladania relácií do dočasných súborov za najbežnejšiu a predvolenú možnosť v PHP).

Po vytvorení novej relácie sa vytvorí súbor s názvom sess_ v adresári nastavenom ako adresár na ukladanie relácií v parametri nastavení PHP session.save_path, kde je identifikátor relácie. Ďalej, v každej požiadavke, v čase spustenia už existujúcej relácie, PHP aktualizuje čas úpravy tohto súboru. V každej nasledujúcej požiadavke teda PHP na základe rozdielu medzi aktuálnym časom a časom poslednej úpravy súboru relácie dokáže určiť, či je relácia aktívna alebo jej životnosť už vypršala. (Mechanizmus odstraňovania starých súborov relácie je podrobnejšie popísaný v ďalšej časti.)

Poznámka: Tu je potrebné poznamenať, že parameter session.gc_maxlifetime platí pre všetky relácie v rámci jedného servera (presnejšie v rámci jedného hlavného PHP procesu). V praxi to znamená, že ak na serveri beží viacero stránok a každá z nich má svoj časový limit nečinnosti používateľa, tak nastavenie tohto parametra na jednej zo stránok povedie k jeho nastaveniu pre iné stránky. To isté platí pre zdieľaný hosting. Aby sa predišlo tejto situácii, pre každú lokalitu v rámci toho istého servera sa používajú samostatné adresáre relácie. Nastavenie cesty k adresáru sessions sa vykonáva pomocou parametra session.save_path v súbore nastavení php.ini alebo volaním funkcie ini_set(). Potom budú relácie každej lokality uložené v samostatných adresároch a parameter session.gc_maxlifetime nastavený na jednej z lokalít bude platný iba pre danú reláciu. Týmto prípadom sa nebudeme podrobne zaoberať, najmä preto, že máme flexibilnejšiu možnosť monitorovania nečinnosti používateľov.

Riadenie nečinnosti používateľa pomocou premenných relácie Zdá sa, že predchádzajúca možnosť pri všetkej svojej jednoduchosti (len pár riadkov kódu navyše) poskytuje všetko, čo potrebujeme. Ale čo ak nie každú požiadavku možno považovať za výsledok aktivity používateľa? Stránka má napríklad časovač, ktorý pravidelne žiada AJAX o prijímanie aktualizácií zo servera. Takúto požiadavku nemožno považovať za aktivitu používateľa, čo znamená, že automatické predlžovanie životnosti relácie nie je v tomto prípade správne. Vieme však, že PHP aktualizuje čas úpravy súboru relácie automaticky pri každom volaní funkcie session_start(), čo znamená, že každá požiadavka povedie k predĺženiu životnosti relácie a časový limit nečinnosti používateľa nikdy nenastane. Navyše posledná poznámka z predchádzajúcej časti o zložitosti parametra session.gc_maxlifetime sa niekomu môže zdať príliš mätúca a ťažko implementovateľná.

Aby sme tento problém vyriešili, upustíme od používania vstavaných mechanizmov PHP a zavedieme niekoľko nových premenných relácie, ktoré nám umožnia sami kontrolovať dobu nečinnosti používateľa.

Funkcia startSession($isUserActivity=true) ( ​​​​$sessionLifetime = 300; if (session_id()) vráti hodnotu true; // Nastaví životnosť súboru cookie pred zatvorením prehliadača (všetko budeme kontrolovať na strane servera) ini_set("session. cookie_lifetime", 0) ; if (! session_start()) return false; $t = time(); if ($sessionLifetime) ( // Ak je nastavený časový limit nečinnosti používateľa, // skontrolujte čas, ktorý uplynul od poslednej aktivity používateľa // (čas poslednej požiadavky, keď bola aktualizovaná premenná relácie lastactivity) if (isset($_SESSION["lastactivity"]) && $t-$_SESSION["lastactivity"] >= $sessionLifetime) ( // Ak čas uplynul od posledná aktivita používateľa, / / ​​je väčšia ako časový limit nečinnosti, čo znamená, že relácia vypršala a musíte reláciu ukončiť zničitSession(); return false; ) else ( // Ak časový limit ešte nenastal, // a ak požiadavka prišla v dôsledku aktivity používateľa, // aktualizujte premennú lastactivity s hodnotou aktuálneho jedného času, // čím sa predĺži čas relácie o ďalšie sekundy sessionLifetime if ($isUserActivity) $_SESSION["lastactivity"] = $t; ) ) vráti true; )

Poďme si to zhrnúť. V každej požiadavke kontrolujeme, či bol dosiahnutý časový limit od poslednej aktivity používateľa do aktuálneho momentu, a ak bol dosiahnutý, zničíme reláciu a prerušíme vykonávanie funkcie s návratom FALSE. Ak časový limit nebol dosiahnutý a do funkcie je odovzdaný parameter $isUserActivity s hodnotou TRUE, aktualizujeme čas poslednej aktivity používateľa. Stačí nám vo volajúcom skripte určiť, či je požiadavka výsledkom aktivity užívateľa, a ak nie, zavolať funkciu startSession s parametrom $isUserActivity nastaveným na FALSE.

Doplnenie zo dňa 2013-06-07 Spracovanie výsledku funkcie sessionStart().

Pripomienky poukázali na to, že vrátenie FALSE neposkytuje úplné pochopenie príčiny chyby, a to je absolútne spravodlivé. Podrobné riešenie chýb som tu nepublikoval (dĺžka článku je už dosť veľká), keďže to priamo nesúvisí s témou článku. Ale vzhľadom na komentáre to vysvetlím.

Ako vidíte, funkcia sessionStart môže vrátiť hodnotu FALSE v dvoch prípadoch. Buď reláciu nebolo možné spustiť kvôli niektorým interným chybám servera (napríklad nesprávne nastavenia relácie v php.ini), alebo vypršala životnosť relácie. V prvom prípade musíme používateľa presmerovať na stránku s chybou oznamujúcou problémy na serveri a formulárom na kontaktovanie podpory. V druhom prípade musíme používateľa preniesť do prihlasovacieho formulára a zobraziť v ňom zodpovedajúcu správu o tom, že relácia vypršala. Aby sme to dosiahli, musíme zadať chybové kódy a vrátiť zodpovedajúci kód namiesto FALSE a v metóde volania ho skontrolovať a podľa toho konať.

Teraz, aj keď relácia na serveri stále existuje, bude zničená pri prvom prístupe, ak vypršal časový limit nečinnosti používateľa. A to sa stane bez ohľadu na to, aká životnosť relácie je nastavená v globálnych nastaveniach PHP.

Poznámka: Čo sa stane, ak bol prehliadač zatvorený a súbor cookie s názvom relácie bol automaticky zničený? Požiadavka na server pri ďalšom otvorení prehliadača nebude obsahovať súbory cookie relácie a server nebude môcť otvoriť reláciu a skontrolovať časový limit nečinnosti používateľa. Pre nás je to ekvivalent vytvorenia novej relácie a žiadnym spôsobom neovplyvňuje funkčnosť ani bezpečnosť. Vynára sa však spravodlivá otázka – kto potom zničí starú reláciu, ak sme ju doteraz zničili po vypršaní časového limitu? Alebo bude teraz navždy visieť v adresári relácií? Na vyčistenie starých relácií v PHP existuje mechanizmus nazývaný garbage collection. Spustí sa v čase ďalšej požiadavky na server a vymaže všetky staré relácie na základe dátumu poslednej úpravy súborov relácie. Mechanizmus zberu odpadu sa však nespúšťa pri každej požiadavke na server. Frekvencia (alebo skôr pravdepodobnosť) spúšťania je určená dvomi parametrami nastavenia session.gc_probability a session.gc_divisor. Výsledkom vydelenia prvého parametra druhým je pravdepodobnosť spustenia mechanizmu zberu odpadu. Preto, aby sa mechanizmus vymazania relácie spustil s každou požiadavkou na server, musia byť tieto parametre nastavené na rovnaké hodnoty, napríklad „1“. Tento prístup zaručuje čistý adresár relácie, ale je zjavne príliš drahý pre server. Preto je na produkčných systémoch predvolená hodnota session.gc_divisor nastavená na 1000, čo znamená, že mechanizmus zbierania odpadu bude bežať s pravdepodobnosťou 1/1000. Ak experimentujete s týmito nastaveniami vo svojom súbore php.ini, môžete si všimnúť, že vo vyššie opísanom prípade, keď sa prehliadač zatvorí a vymaže všetky svoje súbory cookie, v adresári sessions na chvíľu zostali staré relácie. To by vás však nemalo znepokojovať, pretože... ako už bolo uvedené, nijako to neovplyvňuje bezpečnosť nášho mechanizmu.

Aktualizácia zo 7. 6. 2013 Zabránenie zamrznutiu skriptov v dôsledku uzamknutia súboru relácie

Komentáre vyvolali problém zamrznutia súčasne spustených skriptov kvôli zablokovaniu súboru relácie (najvýraznejšou možnosťou je dlhý prieskum).

Na začiatok poznamenám, že tento problém priamo nezávisí od zaťaženia servera alebo počtu používateľov. Samozrejme, čím viac požiadaviek, tým pomalšie sa skripty vykonávajú. Ale toto je nepriama závislosť. Problém nastáva iba v rámci jednej relácie, keď server dostane niekoľko požiadaviek v mene jedného používateľa (napríklad jedna z nich je dlhý prieskum a zvyšok sú bežné požiadavky). Každá požiadavka sa pokúša o prístup k rovnakému súboru relácie, a ak predchádzajúca požiadavka súbor neodomkla, nasledujúca žiadosť zamrzne a čaká.

Ak chcete udržať uzamknutie súboru relácie na minime, dôrazne sa odporúča ukončiť reláciu zavolaním funkcie session_write_close() ihneď po dokončení všetkých akcií s premennými relácie. V praxi to znamená, že by ste nemali všetko ukladať do premenných relácie a pristupovať k nim počas celého vykonávania skriptu. A ak potrebujete uložiť nejaké pracovné údaje do premenných relácie, prečítajte si ich ihneď po spustení relácie, uložte ich do lokálnych premenných na neskoršie použitie a zatvorte reláciu (to znamená zatvorenie relácie pomocou funkcie session_write_close a nezničenie pomocou funkcie session_destroy ).

V našom príklade to znamená, že ihneď po otvorení relácie, skontrolovaní jej životnosti a existencie autorizovaného používateľa, musíme prečítať a uložiť všetky ďalšie premenné relácie požadované aplikáciou (ak nejaké existujú), potom reláciu zavrieť pomocou volania na session_write_close() a pokračovať vo vykonávaní skriptu, či už ide o dlhý prieskum alebo bežnú požiadavku.

Ochrana relácií pred neoprávneným použitím Predstavme si situáciu. Jeden z vašich používateľov získa trójsky kôň, ktorý okradne súbory cookie prehliadača (v ktorých je uložená naša relácia) a odošle ho na zadaný e-mail. Útočník získa súbor cookie a použije ho na sfalšovanie požiadavky v mene nášho oprávneného používateľa. Server úspešne prijme a spracuje túto požiadavku, ako keby prišla od autorizovaného používateľa. Ak nie je implementované dodatočné overenie IP adresy, takýto útok povedie k úspešnému hacknutiu účtu používateľa so všetkými z toho vyplývajúcimi následkami.

Prečo to bolo možné? Je zrejmé, že názov a identifikátor relácie sú vždy rovnaké po celú dobu trvania relácie a ak tieto údaje dostanete, môžete jednoducho odosielať požiadavky v mene iného používateľa (samozrejme počas trvania tejto relácie). Možno nejde o najbežnejší typ útoku, ale teoreticky sa zdá byť celkom uskutočniteľný, najmä ak vezmeme do úvahy, že takýto trójsky kôň ani nepotrebuje administrátorské práva na okradnutie súborov cookie prehliadača používateľa.

Ako sa môžete chrániť pred útokmi tohto druhu? Opäť, samozrejme, obmedzením životnosti identifikátora relácie a pravidelnou zmenou identifikátora v rámci tej istej relácie. Názov relácie môžeme zmeniť aj úplným odstránením starej relácie a vytvorením novej relácie, pričom do nej skopírujeme všetky premenné relácie zo starej. To ale neovplyvňuje podstatu prístupu, preto sa pre jednoduchosť obmedzíme len na identifikátor relácie.

Je jasné, že čím kratšia je životnosť ID relácie, tým kratší čas bude mať útočník na získanie a použitie súborov cookie na vytvorenie používateľskej požiadavky. V ideálnom prípade by mal byť pre každú požiadavku použitý nový identifikátor, čím sa minimalizuje možnosť využitia relácie niekoho iného. Budeme však uvažovať o všeobecnom prípade, keď je čas regenerácie identifikátora relácie nastavený ľubovoľne.

(Vynecháme časť kódu, o ktorej už bola reč).

Funkcia startSession($isUserActivity=true) ( ​​​​​// životnosť identifikátora relácie $idLifetime = 60; ... if ($idLifetime) ( // Ak je nastavená životnosť identifikátora relácie, // skontrolujte čas, ktorý uplynul od relácie vytvorená alebo posledná regenerácia // (čas poslednej požiadavky, keď bola aktualizovaná premenná relácie počiatočný čas) if (isset($_SESSION["starttime"])) (ak ($t-$_SESSION["starttime"] >= $ idLifetime) ( // Čas vypršania životnosti identifikátora relácie // Vygenerovanie nového identifikátora session_regenerate_id(true); $_SESSION["starttime"] = $t; ) ) else ( // Dostaneme sa sem, ak relácia práve vypršala been created // Nastavte čas vygenerovania identifikátora relácie na aktuálny čas $_SESSION["starttime"] = $t; ) ) return true; )

Takže pri vytváraní novej relácie (ktorá nastane po úspešnom prihlásení používateľa) nastavíme premennú relácie starttime, ktorá nám ukladá čas poslednej generácie identifikátora relácie, na hodnotu rovnajúcu sa aktuálnemu času servera. Ďalej v každej požiadavke skontrolujeme, či od posledného vygenerovania identifikátora uplynul dostatočný čas (idLifetime) a ak áno, vygenerujeme nový. Ak teda počas nastavenej životnosti identifikátora útočník, ktorý prijal súbor cookie oprávneného používateľa, nestihne ho použiť, server bude falošnú požiadavku považovať za neoprávnenú a útočníka presmeruje na prihlasovaciu stránku. .

Poznámka: ID novej relácie sa dostane do súboru cookie prehliadača, keď sa zavolá funkcia session_regenerate_id(), ktorá odošle nový súbor cookie, podobne ako funkcia session_start(), takže súbor cookie nemusíme aktualizovať sami.

Ak chceme, aby naše relácie boli čo najbezpečnejšie, stačí nastaviť životnosť identifikátora na jednu alebo dokonca odstrániť funkciu session_regenerate_id() z hranatých zátvoriek a odstrániť všetky kontroly, čo povedie k regenerácii identifikátora v každom žiadosť. (Netestoval som vplyv tohto prístupu na výkon a môžem len povedať, že funkcia session_regenerate_id(true) v podstate vykonáva iba 4 akcie: vygenerovanie nového identifikátora, vytvorenie hlavičky so súborom cookie relácie, odstránenie starého a vytvorenie nový súbor relácie).

Lyrická odbočka: Ak sa ukáže, že trójsky kôň je taký inteligentný, že neposiela súbory cookie útočníkovi, ale zorganizuje odoslanie vopred pripravenej falošnej požiadavky ihneď po prijatí súboru cookie, vyššie opísaná metóda s najväčšou pravdepodobnosťou nebude schopná chrániť pred takýmto útokom, pretože medzi časom, keď trójsky kôň prijme súbor cookie, a odoslaním falošnej požiadavky nebude prakticky žiadny rozdiel a je vysoká pravdepodobnosť, že v tomto momente sa identifikátor relácie nevygeneruje.

Možnosť súčasnej práce v jednom prehliadači v mene viacerých používateľov Poslednou úlohou, ktorú by som rád zvážil, je možnosť súčasnej práce viacerých používateľov v jednom prehliadači. Táto funkcia je užitočná najmä vo fáze testovania, keď potrebujete napodobniť súčasnú prácu používateľov, a je vhodné to urobiť vo svojom obľúbenom prehliadači, a nie používať celý dostupný arzenál alebo otvárať niekoľko inštancií prehliadača v režime inkognito. .

V našich predchádzajúcich príkladoch sme explicitne nešpecifikovali názov relácie, takže bol použitý predvolený názov PHP (PHPSESSID). To znamená, že všetky relácie, ktoré sme doteraz vytvorili, odoslali do prehliadača súbor cookie pod názvom PHPSESSID. Je zrejmé, že ak je názov súboru cookie vždy rovnaký, potom neexistuje spôsob, ako zorganizovať dve relácie s rovnakým názvom v rámci toho istého prehliadača. Ak by sme však pre každého používateľa použili vlastný názov relácie, problém by bol vyriešený. Urobme tak.

Funkcia startSession($isUserActivity=true, $prefix=null) ( ... if (session_id()) vráti hodnotu true; // Ak je v parametroch zadaná predpona používateľa, // nastavte jedinečný názov relácie, ktorý toto obsahuje prefix, // inak nastaviť spoločný názov pre všetkých používateľov (napríklad MYPROJECT) session_name("MYPROJECT".($prefix ? "_".$prefix: "")); ini_set("session.cookie_lifetime", 0); if (! session_start()) vráti false; ... )

Teraz už zostáva len zabezpečiť, aby volajúci skript odovzdal funkcii startSession() jedinečnú predponu pre každého používateľa. Dá sa to urobiť napríklad odovzdaním prefixu v parametroch GET/POST každej požiadavky alebo prostredníctvom dodatočného súboru cookie.

Záver Na záver uvediem kompletný finálny kód našich funkcií pre prácu s PHP sessions, vrátane všetkých vyššie diskutovaných úloh.

Funkcia startSession($isUserActivity=true, $prefix=null) ( $sessionLifetime = 300; $idLifetime = 60; if (session_id()) vráti hodnotu true; session_name("MYPROJECT".($prefix ? "_".$prefix: "")); ini_set("session.cookie_lifetime", 0); if (! session_start()) vráti hodnotu false; $t = time(); if ($sessionLifetime) ( if (isset($_SESSION["lastactivity"] ) && $t-$_SESSION["lastactivity"] >= $sessionLifetime) ( cancelSession(); return false; ) else ( if ($isUserActivity) $_SESSION["lastactivity"] = $t; ) ) if ($idLifetime ) ( if (isset($_SESSION["čas začiatku"])) ( if ($t-$_SESSION["čas začiatku"] >= $idLifetime) ( session_regenerate_id(true); $_SESSION["čas začiatku"] = $t; ) ) else ( $_SESSION["starttime"] = $t; ) ) vráti true; ) funkcia cancelSession() ( if (session_id()) ( session_unset(); setcookie(session_name(), session_id(), time() -60*60*24); session_destroy(); ) )

Dúfam, že tento článok ušetrí čas tým, ktorí sa nikdy príliš neponárali do mechanizmu relácie, a poskytne dostatočný prehľad o tomto mechanizme pre tých, ktorí sa s PHP len začínajú zoznamovať.

Potrebujete používateľské meno a heslo?

Ak chcete posielať články online a kontrolovať stav odoslaných článkov, musíte sa zaregistrovať a prihlásiť sa do svojho účtu.

Kontrolný zoznam na prípravu článku na odoslanie

V rámci procesu odoslania článku musia autori skontrolovať, či ich článok spĺňa všetky nasledujúce body; články môžu byť vrátené autorom, ak tieto požiadavky nespĺňajú.

Článok bol pripravený v súlade s požiadavkami

Podmienky prevodu autorských práv

Autori si ponechávajú autorské práva k dielu a udeľujú časopisu práva na prvé publikovanie spolu s dielom, pričom ho licencujú podľa podmienok Creative Commons Attribution License, ktorá umožňuje ostatným distribuovať toto dielo s povinným uvedením autora diela a odkazom k pôvodnej publikácii v tomto časopise.

Vyhlásenie o ochrane súkromia

Mená a e-mailové adresy zadané na webovej stránke tohto časopisu budú použité výlučne na účely určené týmto časopisom a nebudú použité na žiadny iný účel ani poskytnuté žiadnej inej osobe alebo subjektu.

Používateľ pred registráciou do systému súhlasí so zásadami spracovania a uchovávania osobných údajov.

Autorské platby

1500 znakov s medzerami: 300,00 (RUB)

Vydanie 1 strany rukopisu (1500 znakov) - 300 rubľov. Grafické materiály / tabuľky sa platia samostatne - 50 rubľov / 1 kus. Autorská kópia vrátane dopravy v rámci Ruska sa platí na žiadosť autora - 400 rubľov. Doprava do zahraničia - 800 rubľov. Náklady na odoslanie osvedčenia o prijatí materiálu na zverejnenie sú 150 rubľov.

Preklad sprievodných informácií (celé meno, miesto práce autorov; názov; abstrakt; kľúčové slová) do angličtiny 0,5 rubľov za každý znak vrátane medzier.

Pozor! Autori (kandidáti a doktori vied), ktorí majú podľa elibrary.ru 300 a viac citácií (podiel autocitácií by nemal byť vyšší ako 30 %), sú publikovaní bezplatne. Ak máte nárok na bezplatnú publikáciu, pri odosielaní materiálu uveďte v poli komentárov odkaz na svoj profil knižnice s počtom citácií. Poštovné pri odbere sa platí zvlášť.

Bezpečnosť webových stránok je založená na správe relácií. Keď sa používateľ pripojí na zabezpečenú lokalitu, poskytne prihlasovacie údaje, zvyčajne vo forme používateľského mena a hesla. Webový server netuší, ktorý používateľ je už prihlásený alebo ako prechádza zo stránky na stránku. Mechanizmus relácie zabraňuje používateľom zadávať heslo zakaždým, keď chcú vykonať novú akciu alebo prejsť na novú stránku.

Správa relácií v podstate zaisťuje, že aktuálne pripojený používateľ je ten, ktorý bol overený. Ale bohužiaľ, relácie sa stali jasným cieľom pre hackerov, pretože môžu umožniť prístup k webovému serveru bez potreby autentifikácie.

Po overení používateľa mu webový server poskytne ID relácie. Toto ID je uložené v prehliadači a je nahradené vždy, keď je potrebná autentifikácia. To vám umožní vyhnúť sa opakovaným procesom prihlasovania/zadávania hesla. To všetko sa deje na pozadí a nespôsobuje používateľovi nepohodlie. Predstavte si, že ste zadali svoje používateľské meno a heslo pri každom zobrazení novej stránky!

V tomto článku sa pokúsim načrtnúť všetky spôsoby ochrany ID relácie v PHP, ktoré poznám.

Používanie súborov cookie Štandardne sa všetky informácie o relácii vrátane ID odosielajú do súboru cookie. Ale nie vždy sa to stane. Niektorí používatelia deaktivujú súbory cookie vo svojich prehliadačoch. V tomto prípade prehliadač odovzdá ID relácie v adrese URL.

Tu sa ID prenáša ako čistý text, na rozdiel od relácie prostredníctvom súboru cookie, keď sú informácie skryté v hlavičke HTTP. Najjednoduchším spôsobom, ako sa tomu brániť, by bolo zakázať prenos identifikátora relácie cez panel s adresou. Môžete to urobiť tak, že do konfiguračného súboru .htaccess servera Apache zapíšete nasledovné:

Php_flag session.use_only_cookies zapnuté

Používanie šifrovania Ak vaša lokalita musí spracovávať citlivé informácie, ako sú čísla kreditných kariet (zdravíme vás od Sony), mali by ste použiť šifrovanie SSL3.0 alebo TSL1.0. Ak to chcete urobiť, pri nastavovaní súboru cookie musíte zadať hodnotu true pre parameter secure.

Ak uložíte heslo relácie do premennej $_SESSION (stále je lepšie použiť sql), nemali by ste ho ukladať ako čistý text.

If ($_SESSION["password"] == $userpass) ( // kód )

Vyššie uvedený kód nie je bezpečný, pretože heslo je uložené ako obyčajný text v premennej relácie. Namiesto toho použite šifrovanie md5, niečo takéto:

If ($_SESSION["md5password"] == md5($userpass)) ( // kód )

Kontrola prehliadača Ak chcete zabrániť možnosti použitia relácie z iného prehliadača (počítača), mali by ste zadať kontrolu poľa hlavičky HTTP user-agent:

Session_start(); if (isset($_SESSION["HTTP_USER_AGENT"])) ( if ($_SESSION["HTTP_USER_AGENT"] != md5($_SERVER["HTTP_USER_AGENT"])) ( // kód ) ) else ( $_SESSION["HTTP_USER_AGENT" ] = md5($_SERVER["HTTP_USER_AGENT"]); )

Ukončenie platnosti relácie Obmedzte životnosť relácie, ako aj dobu platnosti súborov cookie. Predvolene je trvanie relácie 1440 sekúnd. Túto hodnotu môžete zmeniť prostredníctvom php.ini a .htaccess. Príklad pre .htaccess:

# Životnosť relácie v sekundách
php_value session.gc_maxlifetime 3600
# Životnosť súborov cookie v sekundách
php_value session.cookie_lifetime 3600

Väzba podľa adresy IP V určitých situáciách (nie vždy) by ste sa mali viazať pomocou adresy IP. Hlavne keď je počet používateľov obmedzený a majú statické IP adresy. Kontrola môže byť buď na základe zoznamu povolených IP adries,

Include("zoznam_ip.php"); //$ip_white_list = pole ("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 "PRÍSTUP ODMIETNUTÝ!"; )

Alebo podľa IP adresy pre každú požiadavku (iba pre statickú IP):

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

Mali by ste si uvedomiť, že hackingu sa nedá úplne vyhnúť. Tento hack môžete sťažiť len tak, ako je to možné, akýmkoľvek známym spôsobom. Nemali by ste však zabúdať ani na svojich legálnych používateľov, aby ste im takouto ochranou nekomplikovali život.

Tento článok bol napísaný v roku 2009 a zostáva jedným z našich najpopulárnejších príspevkov. Ak sa chcete dozvedieť viac o PHP a MySQL, možno vás to bude veľmi zaujímať.

POZNÁMKA: Tento článok bol novo aktualizovaný, aby fungoval na PHP 4.2 alebo novšom!

Nedávno som mal príležitosť pracovať na malom projekte so skupinou ľudí. Už na začiatku sme sa rozhodli, že tento e-mail sám o sebe nebude stačiť na to, aby všetci boli v obraze, a tak som dostal za úlohu vytvoriť malú webovú stránku pre tento projekt. Obsahoval by jednoduchú nástenku, miesto, kde by sme mohli nahrávať dokumenty a iné súbory pre zvyšok tímu, a kontaktné informácie pre rôznych členov tímu.

Aby mnohé z týchto funkcií fungovali, vedel som, že potrebujem, aby sa používatelia prihlásili pred prístupom k relevantným častiam stránky. Potreboval som systém, ktorý by umožnil používateľom zaregistrovať sa na získanie ID používateľa na prístup na stránku a potom toto ID okamžite použiť bez akéhokoľvek zásahu z mojej strany.

V tomto článku poskytnem prehľad systému, ktorý som vyvinul, počnúc prvou polovicou procesu registrácie používateľa. V druhej polovici sa zameriam na samotnú stránku, na to, ako vyžaduje od používateľov prihlásenie a ako potom udržiava stav prihlásenia počas svojej návštevy. Osobitnú pozornosť budem venovať používaniu funkcií správy relácií v PHP. Na konci by ste mali mať všetky informácie, ktoré potrebujete na implementáciu podobného vlastného systému.

V tomto článku budem predpokladať, že máte základné znalosti jazyka PHP, používania formulárov na odosielanie informácií do skriptu PHP a toho, ako možno použiť PHP na interakciu s databázou MySQL. Ak sú pre vás niektoré z týchto pojmov cudzie, mali by ste začať prečítaním môjho predchádzajúceho článku, .

Prvá časť: Proces registrácie Registračný formulár

Prirodzeným miestom na začatie budovania stránky, ktorá bude od používateľov vyžadovať registráciu na prístup, je samotný registračný proces. Ako by sa dalo očakávať, jednoduchý webový formulár bude stačiť. Takto to bude vyzerať:

A tu je kód pre tento formulár:




Registrácia nového užívateľa



Registračný formulár nového používateľa

* označuje povinné pole


S jasným cieľom vás prevediem kódom pre accesscontrol.php . Začnite tým, že zahrniete svoje dva praktické súbory: