Kezdő bakik: web 1x1
A fórumon többször kerülnek elő olyan kérdések, amelyeknek véleményem szerint nem szabadna előkerülniük, ha lenne egy jó leírás arról, hogyan is működik a web. Annak idején én Stefan Münz SelfHTML-jéből tanultam, ami nagyon alapos és módszeres magyarázattal vezeti be a tanulni vágyót a webfejlesztés világába. Egyetlen hibája van: csak németül érhető el. Ugyan ennyire részletes leírásra nem vállalkozhatom, de ezúttal megpróbálom összeszedni a leggyakrabban elkövetett kezdő bakikat.
A haladóbb felhasználók kedvéért elmondom, hogy az itt leírt probléma felvetések nem a teljesség igényével készültek, sok helyen nem írom le a kevésbé triviális példákat. A cél itt az, hogy a kezdők el tudják kerülni a legnagyobb aknákat.
Szerver oldal vs. kliens oldal
Az első, a fórumokon általában erős intoleranciát kiváltó probléma az szokott lenni, ha a kérdező nincs tisztában azzal, mi hol fut. Nézzük meg tehát, hogyan is történik egy weboldal kiszolgálása.
- Beütjük a böngészőnkbe, hogy example.com.
- A böngésző az operációs rendszer segítségével megnézi a domain név milyen IP címhez tartozik.
- A böngésző megnyit egy kapcsolatot a szerver felé (IP cím szerint, itt már nincs domain) és lekéri a kezdőlapot. (Ez a / cím.)
- A szerver megnézi, hogy a kezdőlapra milyen fájlt kell visszaadni (index.html, index.php stb.).
- Ha a fájl valamilyen szerver oldali programozási nyelvben készült (PHP, Perl, Python), a szerver lefuttatja a programot. A program futásának az eredményét adja oda a böngészőnek. (Ergó nem, hacsak nincs hiba a szerver oldali kódban, nem tudod megnézni a forrást!)
- A böngésző a kapott fájlt (pl. HTML) megjeleníti és betölti a hozzá szükséges képeket, egyéb fájlokat illetve elkezdi futtatni a kliens oldali scripteket (pl. JavaScript).
- Ha a felhasználó linkre kattint, vagy mondjuk a JavaScript új adatot kér le, a böngésző új lekérdezést indít.
Mint látható, ez egy oda-vissza adogató játék. Ennek az egyik legfontosabb következménye, hogy nem lehet a JavaScript és a PHP között közvetlenül adatokat átadni, ahhoz új lekérdezést kell intézni a szerverhez.
Munkamenet kezelés
A fentiekből következik, hogy két lekérdezés között nincs olyan adat, ami megmaradna. Ahhoz, hogy adatot tudjunk átadni, munkameneteket kell használnunk. Erről itt a Weblaboron is született már cikk.
A különbség a GET és a POST között
Sokszor képzavar van a GET és POST kérések között, leggyakrabban az űrlapokkal kapcsolatban. Egyszerűen mondva: a GET kérések paraméterei látszanak a címsorban, a POST kéréseké nem. Bónuszként csak POST-tal lehet fájlt feltölteni. Néhány alapszabály:
- Keresést és hasonló dolgokat mindig GET-tel intézünk, hogy lehessen bookmarkolni.
- Módosító, törlő lekérdezéseket kizárólag POST-tal intézünk, különben valakinek küldök egy linket és ha be van lépve, letörli a cikkét. (Ha valaki kekeckedne: előbb átküldöm egy URL rövidítőn keresztül, és akkor biztos megeszi az ismerős.)
- Ez utóbbi esetben kötelező ellenőrizni a szerver oldalon, hogy tényleg POST kérés jött. (
$_REQUEST
-ből olvasni = nem menő).
Működési logika és a kiírás szeparálása
A legtöbb kezdő örül, ha sikerül valahogy összekalapálni a programot, nem igazán gondol a kódszervezésre, viszont a hibakeresésnél létfontosságú lehet. Mit értek ez alatt? Ha például adatot kérünk le adatbázisból, először gyűjtsük össze egy tömbbe, majd utána külön irassuk ki. Ezáltal a kettő között a hibakeresés idejére ki tudjuk iradni az adatot és nem kell nézegetni, hogy vajon a HTML-ben van a hiba, vagy a PHP kódban, ezzel felezve a kódmennyiséget, amiben hiba lehet. Például:
$r = mysql_query("SELECT * FROM comments WHERE topic_id=5");
$comments = array();
while ($a = mysql_fetch_assoc($r)) {
$comments[] = $a;
}
/* Itt irhatjuk ki hibakereses eseten
a tombot, pl igy: var_dump($comments); */
foreach ($comments as $comment) {
echo("Név: " . $comment['name'] . "\n");
echo("Hozzászólás: " . $comment['comment'] . "\n\n");
}
Mennyivel tisztább így. :)
Escape-elés, bemeneti adatok ellenőrzése
Hasonlóan az előzőhöz, a kezdő örül, ha működik, nem igazán gondol a biztonságra. Nézzük a következő kódot:
mysql_query("SELECT COUNT(*) FROM users WHERE username='" . $_POST['user'] . "' AND password='" . $_POST['pass'] . "'");
Mi történik vajon, ha én most azt írom be a password paraméterbe, hogy:
' OR '1'='1
Ez esetben a lekérdezés így fog kinézni:
SELECT COUNT(*) FROM users WHERE username='admin' AND password='' OR '1'='1'
Mi történik? Be tudok lépni adminként, noha nem is volt meg a jelszavam. (A működése szerver beállítástól függhet, de az elvet jól demonstrálja.) Ez esetben a bemeneti adatok ellenőrzésének hiánya egy úgy nevezett SQL injection sebezhetőséghez vezetett. Ennél még sokkal rosszabb is lehett volna, a támadó a nevünkben lefuttathatott volna egy DROP DATABASE
parancsot is. Nézzük a leggyakrabban elkövetett sebezhetőségeket és a védelmi lehetőségeket:
SQL injection
Az SQL injection, mint a fenti demonstráció is mutatja, egy SQL parancs beszúrását jelenti. Ellene úgy kell védekezni, hogy az általunk használt adatbázis kezelő réteg escape függvényét használjuk. PHP MySQL extension esetén ez a mysql_real_escape_string()
. A fenti query tehát helyesen:
mysql_query("SELECT COUNT(*) FROM users WHERE username='" . mysql_real_escape_string($_POST['user']) . "' AND password='" . mysql_real_escape_string($_POST['pass']) . "'");
Figyelem! Senkinek még véletlenül se jusson eszébe, hogy saját szűrő függvényt ír! Az adatbázis rétegek és implementációk változhatnak, valamint közre játszhat a felhasznált karakterkódolás is, így ezek ismerete nélkül szinte lehetetlen jó védelmet írni!
HTML injection, XSS
Ha a felhasználó bemenetet bárhol ki is írjuk (enélkül viszonylag céltalan a dolog), akkor védekeznünk kell a HTML injection és az XSS ellen is. Egy részről azért, hogy ne tudja bárki tetszőleges HTML-lel szétbarmolni az oldalt, másrészt hogy ne tudjon olyan JavaScriptet beszúrni, ami alkalmas a felhasználó belépési adatainak az ellopására. Ha semmilyen HTML-t nem szeretnénk megengedni, akkor PHP esetén elég a htmlspecialchars()
használata.
Ha JavaScriptnek szeretnénk átadni adatot, akkor azt a json_encode()
hívással kell escape-elni.
Tanács: az ilyen escape-elést a kiíráskor végezzük, ne az adatok mentésekor. Így ha esetleg módosításokra van szükség a szűrő algoritmuson, nem kell újra konvertálnunk a már meglevő adatokat. Ezen felül ha változtatunk a kimeneti formátumon (például HTML helyett JSON-t küldünk), akkor igen csak nagy gondban lehetünk.
URL injection
Ha a felhasználó által adott értékeket linkbe írjuk, ki kell védenünk azt, hogy tetszőleges GET paramétert tudjon manipulálni az által, hogy beír egy kérdőjelet vagy egyenlőség jelet. Az ilyen irányú védelemre az urlencode()
függvényt kell használni. Például így:
echo('<a href="/kereses?q=' . urlencode($elozokereses) '">előző keresés</a>');
CSRF
A CSRF jóval trükkösebb jószág. Legegyszerűbb példaként azt lehetne fölhozni, hogy valaki egy idegen oldalon csinál egy láthatatlan űrlapot, ami a mi oldalunkra küldődik el. Ha a felhasználó be van lépve mondjuk az admin oldalra, azt is elérheti a preparált oldal, hogy töröljük valamelyik cikkünket. Védekezni ez ellen nem egyszerű, a munkamenetünkbe be kell helyeznünk egy munkamenetenként egyedi változót (cannary), amit a formok elküldésekor ellenőrzünk. Ha nem stimmel, hibát írunk ki. Mivel a felhasználónak kiosztott cannaryhoz a másik oldal nem fér hozzá, ezért nem fogja tudni elküldeni a formot.
URL manipulation
Ha valamilyen paraméterek vannak az URL-ben, akkor nézzük meg, mi történik, ha manipuláljuk őket. Ha nem ellenőrizzük őket, könnyen lehet, hogy a felhasználó hozzá tud férni olyan dolgokhoz, amikhez nem kellene neki. Soha, de soha ne feltételezzük, hogy a felhasználó nem tudja, mit kell beírni a címsorba! A gyakorlat azt mutatja, hogy de, tudja. Megtalálja.
Remote code execution
Ez minden sebezhetőség lerondábbika. Hál' istennek nem gyakran fordul elő, de ha előfordul, akkor a támadó a szó legszorosabb értelmében bármit megtehet a weboldalunkon.
Leginkább akkor vagyunk veszélyben, ha a felhasználó által feltöltött adatot fájlba tesszük, majd include
vagy require
paranccsal olvassuk fel, illetve ha a rendszerünkben shell (shell_exec()
, exec
stb.) vagy eval()
hívások vannak.
A védekezés egyszerű: ne használjunk ilyen hívásokat. Az esetek 99%-ában ezekre semmi szükség, pusztán a programozó volt lusta rendesen megírni a kódot.
Gyakorlati példa: Az egyik ilyen díszpinty az e107 rendszer volt, ahol a contact.php-ba szültek egy sebezhetőséget, aminek következtében a támadó a rendszeren elindíthatott egy programot a háttérben, ami elkezdte önmagát tovább terjeszteni és a helyi szervert zúzni. Hogy hogy sikerült ezt elkövetniük, foglamam sincs, de úgy általában jellemzi az e107 biztonságát és úgy általában kezet foghat a PHPFusion nevű haverjával. Persze szigorúan a személyes magánvéleményem szerint.
Karakterkódolás
Amin szinte minden kezdő elvérzik, ha nem előbb, akkor utóbb egy oldal költöztetésnél, az a karakterkódolás. Ez azért problémás, mert ha egyszer rosszul van bent az adatbázisban az adat, közel lehetetlen helyre rakni, főleg a szolgáltatás teljes leállítása nélkül
Az átlag weboldalnak három pontja van, ahol el lehet ezzel csúszni:
- A böngésző. A HTML karakterkódolását a Content-Type HTTP fejlécben vagy
<meta>
tagben tudjuk megadni. Az előbbi erősebb, mint az utóbbi, tehát ha a szerver gazdája beállított valamit, akkor a<meta>
nem segít. - A MySQL kapcsolat. Akármilyen furán hangzik, a MySQL kapcsolat és az eltárolt adat karakterkódolása nem feltétlenül azonos. A szerver automatikusan konvertál. Ha ezt nem jól állítjuk be, akkor az adatbázisban az ő szemszögéből értelmezhetetlen bináris szemét lesz, ami exportáláskor arcon is csapja az ember amolyan péklapát-stílusban.
- A MySQL adatbázis. Ha a táblák karakterkódolását nem jól állítjuk be, könnyen lehet, hogy a magyar ékezetes karaktereink elvesznek.
Best practice elven javaslom, hogy mindhárom karakterkódolás legyen azonos! Ha valahol inkonzisztencia lép fel, végeláthatatlan karakterkonverziós szívások lépnek fel! Mivel ma már minden weben haszált program támogatja az UTF-8-at, érdemes azt használni.
Gyorstalpaló a megfelelő lépések betartására:
- PHP-ból küldjük ki a megfelelő fejléceket:
header("Content-Type: text/html; charset=UTF-8");
- A MySQL-hez való kapcsolódás után állítsuk be a kapcsolat karakterkódolását:
mysql_query("SET NAMES utf8");
- MySQL tábla létrehozáskor biggyesszük oda a karakterkódolást:
CREATE TABLE t1 (…) CHARACTER SET utf8 COLLATE utf8_general_ci;
Fórum tippek
Ha a fórumban kérdezel (nem csak itt, máshol is), érdemes úgy megszerkeszteni a kérdést, hogy a közösség az értelmezés helyett a probléma megoldására fordíthassa az agykapacitását. Erről külön blogbejegyzésben értekezem.
■
Nemzeti alaptanterv
Jó post, várjuk a többit.
Ez lesz az a bejegyzés a
Már nagyon-nagyon régen meg kellett volna írni, mert az esetek 95%-ában ilyeneket kérdeznek a fórumokon. Szép munka! :-)
Szerintem létre lehetne hozni valami FAQ vagy kezdőknek vagy hasonló menüpontot, ahova az ilyenek bekerülnének. Szerintem van még néhány téma, ami ide tartozna, pl: egy webszerver telepítése, vagy svn telepítése és használata, és még sorolhatnám...
Szép munka, remélem lesz
Számomra nagyon hasznos volt az írás, nagyon jó kis összefoglaló volt.
Wiki volt
Anno pont proclub vezényletével indult meg a Weblabor Wiki projekt, ami kellő támogatás nélkül elapadt, ha jól tudom. Ha a jövőben proclub és mások tollából megindul az ilyen irányú cikkek publikálása a WL-en, akkor valóban lehet értelme majd egy FAQ rovatba sorolni őket.
Hát erről a wikiről nem
(Mindenestre ha lesz a későbbiekben kezdőknek szóló rovat, akkor légyszi ne FAQ legyen a neve, mert elég csúnya egy angol rövidítés egy magyar nyelvű menüben.)
Hmm azt hiszem a későbbiekben
és valahogy minden kifért
Nagyszerű hogy leírtad
2010-et írunk, de 'programozók' olyan kódokat csinálnak, hogy pillanatok alatt kifekteted. (ez már 5 évvel ezelőtt is gáz volt.)
Már sokszor beszéltem kezdőknek a fentiekről, de egyszerűbb gagyi kódot írni és _REQUEST tömböt piszkálni (messziről, bottal). Mint néhány alapszabályt betartani és a biztonság lebegjen a szem előtt.
ez biztos?
Hát végül is lehet mondani, egy számítógépen majdnem minden az operációs rendszer segítségével történik. :)
pár fontos apróság
Lenne viszont pár észrevételem (elnézést, ha olyan is van, amit előttem már leírt valaki).
Szerver oldal vs. kliens oldal:
A böngésző megnyit egy kapcsolatot a szerver felé (IP cím szerint, itt már nincs domain) és lekéri a kezdőlapot. (Ez a / cím.)
Itt én talán kivenném a zárójelet. Ugyan szigorú értelemben valóban nincs már név feloldás, azonban a HTTP lekérésben eljut a szerverhez a domén neve, és a kiszolgáló fel is dolgozza azt. Nem ártana megemlíteni szerintem (linkelni) hogy a kérések a HTTP protokolon keresztül zajlanak, aminek pontos leírása elérhető, ez a leírás a 2616-os RFC. Az, hogy valaki kezdő, nem jelenti, hogy nem fogja legalább átfutva megpróbálni megérteni (sőt, tapasztalatom, hogy nagyon sok középhaladónak sincs arról halovány gőze, hogy valójában hogyan működik ez a kliens-szerver kapcsolat, és mit miért úgy kell ahogyan).
A különbség a GET és a POST között:
Itt talán a legfontosabb különbség hiányzott: a GET lekérés hossza korlátos (böngészőtől függő, de néhány száz karakter), míg a POST-é nem. Ez magyarázza a többi pontot is.
Azt, hogy a kérés GET volt-e vagy POST ellenőrizni felesleges. Ez egy félreértés: a POST lekérés semmivel sem különlegesebb (vagy nem sokkal), mint a GET, telnet kliensben egy sima POST lekérést megírni ugyanannyi, mint egy GET-et. Vagy ha valaki idáig nem süllyed, CSRF-fel még mindig simán átverheti a szervert. Tehát sokkal célszerűbbnek tartok minden mást vizsgálni, mint ezt, mivel könnyen hamisítható. És itt mondjuk utalnék is a szépen összeszedett biztonsági problémákra. Tulajdonképp még senki nem tudott nekem meggyőző érvet mondani arra, hogy miért jó ellenőrizni a lekérés típusát biztonsági célból.
A kárhoztatott $_REQUEST változó használatával pedig csak annyi probléma van (és EZT érdemes ellenőrizni viszont), hogy ha egy űrlap POST-ként kerül elküldésre, de a request URI-ben (ez a <form> tag action paraméterének értéke) is szerepelnek paraméterek, akkor a PHP a request URI-ből vett paramétereket a $_GET tömbbe fogja tenni, a POST-ban szereplő (az űrlap mezőitől kapott) értékeket a $_POST-ba, DE ha a $_GET-ben és a $_POST-ban szerepel azonos nevű paraméter különböző értékkel, akkor a $_REQUEST-ben csak a POST érték fog szerepelni! Az ilyen esetek viszont kis odafigyeléssel elkerülhetőek, ha az űrlapok kialakításánál ügyelünk arra, hogy az action paraméterben ne szerepeljen a lekérésben olyan paraméter, amit név szerint megkap a szerver egy űrlapmezőtől is!
Példakód (csúf, de hasznos, nem valid :-P):
Ebben a fejezetben ha már szó esik az adatbázis kezelésről, már csak népnevelő célzattal is megérdemelt volna szerintem egy linket a PDO is, hátha vannak olyan kezdő webfejlesztők, akik korábban már találkoztak valamilyen objektum-orientált nyelvvel. A PDO használatához egyébként még annyira nagy OO ismeret sem szükséges, lényegesen egyszerűbb sok szempontból mint a xyz_query() és társai, tekintve hogy szabványos a felülete, azaz független az adatbázis elérő rétegtől (például az említett escape-elés is, amit egyébként PREPARE lekérés esetén a PDO automatikusan megcsinál).
Karakterkódolás:
A három pont valójában négy! A munkafájlok (php kód, HTML sablonok, JS-ek, stb) mind UTF-8 kódolásúak kell hogy legyenek egységesen, különben ez a fejezet semmit se fog érni, hibásan enkódolt karakterek (ő, ű feltétlen) továbbra is meg fognak jelenni, ha azok fájlban szerepelnek (pl. űrlapmező előtti címkeként a sablonban)!
Biztonsági kérdésekhez:
Lehet, hogy a hivatkozott cikk a munkafolyamatokról kifejti, de az injection-ök és egyéb hasonszőrűek közt csak az említés szintjén (esetleg újra hivatkozva) megemlíteném a session biztonsági problémákat is, azaz hogy a munkafolyamatokkal illetéktelenek - a megfelelő ellenőrzések elvégzése hiányában - könnyen visszaélhetnek egy belépett felhasználó jogosultságaival. A munkafolyamat ellopható!
Ugyanitt elmondanám azt is, hogy a CSRF-ek védhetőek a munkafolyamatok bevezetésével (és a felhasználó $_SESSION változóban való azonosításával), ugyanis ha az ellopott űrlaphoz nem tartozik munkafolyamat, akkor nem futtatható egy belépett felhasználó nevében. Egyébként ugyanitt linkelném ezt is: Munkamenet kezelés biztonsági kérdései
És bocsánat, hogy ennyi haladó szottyot írtam, de úgy gondoltam, ha netán egyik-másik észrevételem alapján visszamódosításra kerül a bejegyzés, akkor ahhoz a szakmai érvek nem ártanak, a bejegyzés nyelvezete viszont maradhat az, ami volt (én ennyire fogyasztható módon nem tudok fogalmazni, ezt az íróra bíznám, mert neki jól láthatóan megy).
GET - POST ellenőrizés
...Tulajdonképp még senki nem tudott nekem meggyőző érvet mondani arra, hogy miért jó ellenőrizni a lekérés típusát biztonsági célból.
cikkből idézve:
CSRF tamadas POST-ot is
a post vs get inkabb a szemantikus web, illetve usability miatt fontos.
post-olt oldalt nem tudok egyszeruen bookmarkolni, share-elni, illetve ha mar van HEAD, GET, PUT, POST, DELETE az RFC-ben, akkor erdemes lehet hasznalni, es ezaltal utalni a method-dal, hogy mi tortenik a hatterben (ugyanitt erdemes lehet a response kodokat megemliteni).
tehat szerintem tisztan security szempontbol nem jobb egyik, mint a masik.
Tyrael
Valamint ha egy GET
ez nem biztonsagi szempont,
amugy egyik haverom jart ugy, hogy sehol nem publikalt weblap publicbol elerheto, de sehol nem linkelt cronjobjat kezdte el hivogatni valami (mondtam hogy ne ugy csinalja, hosszu tortenet), mire kideritettuk, hogy fent volt nala az alexa toolbar, ami hazakuldte hogy milyen url-eket nezett meg a bongeszobol, majd ezeket az alexa crawler-e megprobalta felindexelni...
szoval ilyen is van
Tyrael
nagyságrend
Szomszéd pistike miután szakított a barátnőjével küldöd neki egy olyan linket amire ha rákattintva a volt barátnő akaratlanul töröli az összes levelét. (wwww.emailszolgaltato.hu/mail?action=mailDeleteAll)
Jó oké ezt post-al is meglehet játszani, de azért get-el egy nagyságrenddel könnyebb.
(használd egészséggel, de én nem biztonsági szempontból nem tanácsolnám hosszú távon)
manapsag ugye a csrf
onnan pedig mar mind1, hogy direktbe a mailDeleteAll az getet vagy postot var egeszen addig amig van js a kliens bongeszojeben (ami manapsag majd mindenutt van).
ha post kell, akkor a href.hu-s link a tamado sajat oldalara fog dobni, ami js-bol eltolja a postot.
sot ha nagyon otletesek akarunk lenni, akkor akar egy A site XSS sebezhetoseget is ki tudjuk hasznalni ugropontnak a B site-ra valo CSRF-hez, igy meg sajat tarhelyet sem kell regisztralnunk/fenttartanunk, vagy hasznalhatunk akar egy http://jsbin.com -hoz hasonlo szolgaltatast is.
Tyrael
értelek ám
Viszont akkor közelítsük meg máshonnan a témát: ha valaki "fel akarja törni" az oldalad, biztos lehetsz benne hogy az elsők között lesz az hogy megnézi hogy használják-e a $_GET[], $_POST[]-ot, mert általában a $_REQUEST[]-őt a kezdők használják, és ennek következtében jó esélyel feltörhető az oldal, ergó érdemes küzdeni vele.
Én ezt mind tudom hidd
nem voltam biztos benne a hozzaszolasod alapjan
ha valaki fel akarja torni a site-odat, akkor elso korben fog nyomni par blind code/sql injectiont, ha ezek nem jonnek be, akkor csinal egy alaposabb terkepet a rendszerrol (portscan, szolgaltatasok verzioinak megszerzese, a webalkalmazás belépési pontjainak feltérképezése, social engineering, etc.) ez alapján pedig elkezdi módszeresen végigpróbálgatni azokat a sebezhetőségeket, amik a legkevesebb munkával, a legtöbb eredményt igérik.
Nem azért lesz sebezhető a REQUEST sem, mert a Cookie felülcsaphatja a POST-ban tárolt azonos nevű változót vagy fordítva a $_REQUEST tömbben, hanem mert nem megfelelően vannak validálva a klienstől érkező adatok.
Számomra a post, vagy cookie változók ugyanolyan "gyanúsak" mint a getben kapottak.
Innentől kezdve az én kódom nem lesz kevésbé biztonságos ha a $_POST helyett a requestet használom, a legroszabb ami történhet, hogy van 2 azonos nevü, de eltérő funkcióju változom(ami már eleve gáz megoldás) amik a ráadásul egy funkción belül szükségesek (tehát van egy oldalam, amit post-tal várok, de az url-ből is használom az azonos nevű get parametert => megatakony), es ebben az esetben az a funkcio nem vagy nem megfeleloen fog mukodni (de a szabalytalan mukodes nem lehet biztonsagi problema, hiszen a klienstol erkezo adatok validalva vannak).
persze ez csak az en velemenyem, de szerintem maga a REQUEST nem biztonsagi tenyezo, esetleg ahogy te is mondtad, gyakran jarhat egyutt a REQUEST hasznalata mas problemakkal is, de ez nem ok-okozati osszefugges szerintem.
viszont sikerult elerni vele, hogy egy amugy artalmatlan eszkoz ki lett kialtva egbekiallto biztonsagi problemanak.
ps:
az ilyen "általában" általánosításokkal jól lehet érvelni egy vitában, de általában kiderül, hogy nem a valóságot, hanem az általánosító ember szűk környezetét tükrözik.
Tyrael
re
nem voltam biztos benne a hozzaszolasod alapjan
-szerintem hülyességet nemírtam...
hozzászólásod középső részére nem reagálnék mert totál egyetértek/igazat írtál.
gyakran jarhat egyutt a REQUEST hasznalata mas problemakkal is, de ez nem ok-okozati osszefugges szerintem.
-erre akkartam célozni (ezekszerint túl röviden írtam)
az ilyen "általában" általánosításokkal jól lehet érvelni egy vitában, de általában kiderül, hogy nem a valóságot, hanem az általánosító ember szűk környezetét tükrözik.
-meglehet. Akkor átfogalmazom: tapasztalatom szerint aki a REQUEST-et használja az nagy valószínüséggel kezdő. De örülök hogy te a nem ilyen kódokkal találkozol.
off: én azért nem használom a REQUEST[]-őt mert szeretem látni hogy az a változó honnan jött. (ha fél év után kell ránézzek a kódra akkor meg pláne)
DE ha a $_GET-ben és a
Ez így ebben a formában nem igaz, ugyanis ez a variables_order PHP beállítástól függ, habár alapértelmezésben ez
EGPCS
. Azaz a POST változók felül fogják írni a GET változókat, DE a COOKIE változók is felül fogják ezeket írni, amit meg ugye szintén könnyű hamisítani, ezért a$_REQUEST
használata messze kerülendő, kivéve, ha nagyon tudjuk, mit csinálunk.CSRF, SESSION
Ez így nem pontos. A CSRF lényege, hogy az áldozat maga küldi el a kérést. Egy megoldás lehet, hogy az űrlapban küldünk egy plusz azonosítót is, amit tárolunk a munkamenetben is.
Továbbá, mint előttem írták, a POST "biztonságosabb" CSRF tekintetében, mint a GET, ugyanis (AFAIK) nem tudsz olyan linket elküldeni az áldozatnak, ami POST kérést hajtana végre.
Ez így nem pontos. A CSRF
Nem az áldozat, hanem a támadó domain küldi a kérést az áldozat böngészőjén keresztül úgy, hogy az áldozat erről semmit nem tud.
Ettől függetlenül a munkafolyamat csak nagyon gyenge védelmet ad, hiszen munkafolyamatot is lehet indíttatni CSRF-el ugyanúgy, mint bármilyen más kérést.
ez sajna nem
http://www.cgisecurity.com/csrf-faq.html#post
Tyrael
Wiki
Részemről:
- a GET és a POST közötti különbséget nagyon jól leírna a nevük - a GET-tel kérünk valamit (tartalmat), a POST-tal küldünk (formot, valamiféle utasítást)
- a CSRF-re alapvető védelmet nyújt a tokenek használata
Továbbá nem láttam és nagyon fontos:
Ha felhasználók adatait rögzítjük, a lehető legóvatosabban kell eljárnunk. a jelszó mindenképpen hash-elve (salting!) legyen eltárolva - hash =/= encyption! Nagy méretű adatbázis esetén a felhasználók e-mail címét és személyes adatait tároljuk valamilyen titkosító algoritmussal.
Azt kell feltételeznünk, hogy az adatbázishoz bárki hozzáfér.
Mellesleg 1x1 témáan nekem referencia:
http://stackoverflow.com/questions/72394/what-should-a-developer-know-before-building-a-public-web-site
Köszönöm
Köszönöm a rengeteg hasznos hozzászólást és elnézéseteket kérem, hogy csak most reagálok, de külföldön voltam, amikor kikerült az írás.
Az egyetlen dolog, amit javítandónak érzek, az a fájl karakterkódolása és a BOM karakterek, ezt korrigálni fogom, amint gép elé jutok. A többi témában engedelmetekkel a kommentjeiteket hagynám itt pontosítás, kiegészítés gyanánt.
Ami a wikit illeti, nagyon kiesett a Weblabor vérkeringéséből, ezért egy idő után elhalt. Azt javaslom, egy külön tartalmi rendszer helyett csináljunk egy sitemap-szerű indexet a cikkekről a már meglevő tagek alapján. Ha valaki ért a Drupal fejlesztéshez és van szabadideje, alkothatna egy ilyet.
További kellemes hétvégét:
János
$_request miért ne?
Kezdőként olyan nagyon nem derült ki világosan számomra, hogy a $_request használata miért nem támogatott.. (Mikor elég sok PHP oktatókönyv ennek használatát okítja)
Felhomályosítana valaki?
Köszönöm
Lásd korábban
$_REQUEST
-tel.Idézetek az oldalról:
Honnan jött?
Szóval ne használjunk
Szűrjük a bemenő adatokat - OK.
ahogy kihámozom a szövegből a 'cookie változók' felülírják a GET és POST adatokat is - OK.
Akkormárcsak azt kérdezném - kezdőként, "...aki örül ha összekalapál egy működő kódot"
hogy amolyan "..best practice"-ként $request helyett MIT és HOGYAN ajánlott használni?
Re: Szóval ne használjunk
A COOKIE-k pedig nem feltétlenül írják felül a többit, lásd: php.net vonatkozó írását, melyet már valaki korábban linket.
Egyébként én életemben nem használtam a $_REQUEST tömböt ...
apró megjegyzés
kicsit pontosabban: Felhasználótól érkező minden adatot szűrjünk! (pl. $_SERVER tömb értékeit szeretik elfejteni)
Karakterkódolás string függvényeknél
az UTF-8 kódolást a PHP beépített string kezelő függvényei nem támogatják maradéktalanul.
Rövid példa:
echo strlen($str); // 6
echo mb_strlen($str, 'utf-8'); // 3
Ezt is odacsapnám a karakterkódolásos részhez, egyébként remek írás!
json_encode()
Én kézzel kódolom, mert régebben nem működött, mostanában meg nem néztem.