Autor | Zpráva | ||
---|---|---|---|
34111 Profil |
Ahoj,
řeším trvalé přihlášení uživatelů. Prosím o radu. Nejprve jsem si vytvořil zápis trvalého přihlášení resp. ID a tokenu do databáze, to funguje v pohodě: $token = md5(uniqid(mt_rand(), true)); setcookie("trvale_prihlaseni", "$_SESSION[id]:$token", strtotime("+1 month")); mysql_query(" INSERT INTO users_logged (id_user, token) VALUES ($_SESSION[id], '$token') "); Při přihlášení uživatele se do tabulky user_logged zapíše potřebná hodnota tokenu a ID. Jenže teď potřebuji na začátku nejlépe v hlavičce celého webu ověřit, zda je či není ten který uživatel přihlášen a pokud je, tak např. definovat nějakou proměnnou na hodnotu true a pokud není, tak na hodnotu false a také uložit do nějaké proměnné hodnotu ID uživatele, abych dále věděl, který je přihlášený a mohl dle toho zobrazovat věci na stránce. Mám tu toto: list($id_user, $token) = explode(":", $_COOKIE["trvale_prihlaseni"], 2); mysql_result(mysql_query(" SELECT COUNT(*) FROM users_logged WHERE id_user = " . intval($id_user) . " AND token = '" . mysql_real_escape_string($token) . "' "), 0); Jenže $id_user i $token jsou prázdné..... A ani pořádně netuším, jak je vypsat, můžete mi někdo poradit? |
||
34111 Profil |
#2 · Zasláno: 30. 6. 2016, 16:55:13
Aktualizace:
tak jsem si při zjišťování hodnoty v cookies ve srovnání s databází napsal toto: list($id, $token) = explode(":", $_COOKIE["trvale_prihlaseni"], 2); $autologin = mysql_result(mysql_query(" SELECT COUNT(*) FROM users_logged WHERE id_user = " . intval($id) . " AND token = '" . mysql_real_escape_string($token) . "' "), 0); echo "$autologin"; Bohužel proměnná $autologin má i v případě, že zápis do databáze proběhl dobře hodnotu nula. To znamená, že hodnota cookie "trvale_prihlaseni" je prázdná, zatím nevím, proč... |
||
Martin2 Profil * |
#3 · Zasláno: 30. 6. 2016, 17:44:46
Pořiď si PHP editor s debuggerem, podívej se na hodnoty proměnných a přestaň používat funkce md5, uniqid a mysql_*.
Mimochodem, tímto způsobem trvalé autentizace vytváříš bezpečnostní slabinu. Kompromitace tokenů dokáže úplně obejít přihlášení. |
||
34111 Profil |
#4 · Zasláno: 1. 7. 2016, 10:43:33
Martin2:
Ahoj, tak vše jsem nakonec rozchodil, ale docela by mě zajímalo, pokud tedy říkáš, že tento způsob je děravý, jaký způsob tedy mám používat? Na celém googlu se nedá o tomhle nic najít a tento způsob je všude uveden jako bezpečný. Jak konkrétně myslíš "kompromitovat" token? Vždyť ten token se nedá vyčíst jinak než zneužitím dat z databáze - value v cookie samozřejmě neodpovídá tokenu tzn. ten token je možno číst uvnitř PHP skriptu vypsáním hodnoty proměnné (a to uživatel těžko udělá) a nebo je přítomen v databázi a plkud se mi už někdo dostane do databáze, tak už může zneužít v podstatě vše.. Nebo mi naznač, jak, ať přemýšlím jak přemýšlím, tak nemohu nic vymyslet. |
||
TomasJ Profil |
Martin2:
Věděl jsi, že když ti někdo z prohlížeče "ukradne" SESSION ID, obejde přihlášení úplně stejně jako když ukradne jiný token? Martin Brodecký: Podle mě to až tak děravé není, ale... Máš tam zbytečné to ID. Token by měl být unikátní, čímž jsi schopen z databáze vytáhnout právě jeden záznam pro daný token (a u něj bude zapsáno i ID). Opravdu používej raději mysqli, než mysql (je zastaralé a možná už i nefunkční). Pokud jsi zvyklý na zápis mysql_*, v mysqli je to v podstatě totožné, až na přidané písmeno "i" za "mysql". Je třeba počítat s tím (snad se nepletu), že cookie nastavené skriptem PHP, je dostupné až při dalším načtení stránky. Ovšem tím už si nejsem jistý, PHP se již nějaký čas nevěnuji. Edit: Udělal bych ověření, jestli jsou či nejsou prázdné proměnné $id a $token. Pokud ano, cookie je prázdné. Pokud ne, zkusil bych dotaz na DB, ale místo COUNT(*) bych nechal * (všechny sloupce) a následně si vypsal, co to vlastně vrátí (mysql_fetch_*). Pak ještě zkus vypsat mysql_error a zjistit jestli v tom někde nemáš chybu. |
||
Martin2 Profil * |
#6 · Zasláno: 2. 7. 2016, 00:01:28
TomasJ:
„Věděl jsi, že když ti někdo z prohlížeče "ukradne" SESSION ID, obejde přihlášení úplně stejně jako když ukradne jiný token?“ Ne tak docela. Session je většinou krátkodobá, v řádu hodin, nikoliv dnů nebo dokonce týdnů. Kromě toho – session id je odděleno od databázových dat. Umístěním autentizačního tokenu do databáze je v podstatě popření smyslu hashování hesla – je to věc, kterou lze ukrást a použít k přihlášení do aplikace. |
||
TomasJ Profil |
Martin2:
Myslíš, že když někdo ovládne přístup k tvé DB, bude ho zajímat pouhý přihlašovací token? V tomto okamžiku už si s DB může dělat co chce. Pokud někdo udělá SQL inject, je chyba programátora že to neošetřil. Od toho je *_real_escape_string. |
||
Martin2 Profil * |
#8 · Zasláno: 2. 7. 2016, 00:31:21
TomasJ:
„Myslíš, že když někdo ovládne přístup k tvé DB, bude ho zajímat pouhý přihlašovací token?“ To není relevantní. Umístěním autentizačního tokenu do databáze oslabuješ bezpečnost své aplikace, protože vytváříš něco, co lze ukrást a použít k přihlášení (což může být MNOHEM horší než pouhá ztráta dat). |
||
TomasJ Profil |
#9 · Zasláno: 2. 7. 2016, 08:30:36
Martin2:
Mohli bychom se o tom, co je horší, dohadovat měsíc. Vím, jak funguje OAuth2 zabezpečení. Funguje na něm i Google autorizace. Ukládá do DB přístupový (access) a obnovovací (refresh) token. Přístupový platí obvykle platí jen hodinu, obnovovací klidně 7 dní a déle. Pomocí obnovovacího se dá vygenerovat nový přístupový. Představ si, že jim někdo ukradne data. Je to jen o tom, jak máš zabezpečený přístup do DB a ošetřený vstup od uživatele. Pokud ani jedno nemáš dokonale, pak máš opravdu větší problém než ztrátu tokenů, které můžeš z DB smazat a vše bude fungovat dál bez problémů. |
||
Časová prodleva: 9 let
|
0