CSRF védekezés, jogok kiosztása, captcha használat
Sokat agyaltam azon, hogy milyen rendszerrel lehet megoldani a CSRF védekezést hatékonyan: most megszületett a megoldás.
Ami nyilvánvaló, hogy pusztán a HTTP referrer nem elég, mert nem támogatja az összes böngésző, emiatt ki kell küldeni egy olyan azonosítót, amit POST-ban visszaküld a felhasználó az űrlappal, és ezzel érvényesíti a kérését.
A gyakorlatban elég lenne pusztán annyi, hogy bejelentkezéskor az illető kap egy ilyen azonosítót (ezentúl: postId
), és utána az összes űrlapjához ezt használja a hitelesítésre. Ez nagyon egyszerű és jól használható módszer.
Ha feltételezzük, hogy egy űrlapnak csak egy feldolgozója lehet (Ajax használatakor ez nem biztos), akkor viszont lehetséges az, hogy minden egyes űrlapot külön azonosítsunk. Ennek önmagában nem sok jelentősége van, viszont a későbbiekben kiderül, hogy össze lehet kapcsolni egy captchaval kapcsolatos probléma megoldásával és a jogok kezelésével.
A captchat szinte az összes helyen úgy használják, hogy egyszerre csak egy captcha van a sessionben, és az összes űrlapot azzal a captchaval lehet hitelesíteni. Ez azt eredményezi, hogyha egyszerre több captchas űrlap van megnyitva, akkor mindig a legutóbb megnyitott captchaját kell beírni bármelyikbe. Ez olyan alkalmazásoknál idegesítő lehet, ahol gyakran használnak captchat. Én konkrétan egy olyan oldalon futottam bele, ahonnan könyveket lehet letölteni a captcha beírása után. Először végignéztem a könyveket, hogy melyek azok, amik nekem kellenek, megnyitottam őket, megkaptam az űrlapjukat. Aztán amikor elkezdtem egymás után letölteni őket, akkor a letöltés előtt mindig frissítenem kellett az oldalt, hogy a megfelelő captcha képet lássam. Ez elég idegesítő volt.
A megoldás erre a problémára az lehet, hogyha a captcha képet és kódot hozzákötjük az aktuális űrlaphoz. Ehhez viszont tudni kell minden egyes űrlapot egyenként azonosítani.
A témához még hozzá tartozik a jogosultságok kezelése is. Én a jogok kezelését úgy oldottam meg, hogy az actionöket egyesével engedélyezem. Ez az én rendszeremben valahogy így megy:
$permissions=array(
'Www' => array(
'Articles' => array(
'read' => true,
'write' => true
)
)
);
Itt a www aldoménre az articles
service (controller) read
és write
actionjei (metódus) engedélyezettek a felhasználó számára. Persze más rendszerek máshogy épülnek fel. A lényeg, hogyha bent van egy action a tömbben, akkor nálam joga van a felhasználónak használni azt; ha pedig nincs bent, akkor nincs joga hozzá.
Ha feltételezzük azt, hogy egy bizonyos űrlapot csak egy action dolgozhat fel (Ajax használatakor ez nem egyértelmű), akkor az egyes űrlapokat hozzá lehet kötni az őket feldolgozó actionhöz.
Az előzőekben az űrlap típusát az actionhöz kötöttük, az aktuális űrlapot a postId
-hez, a captchat pedig az aktuális űrlaphoz. Ezekből a kapcsolatokból látszik, hogy egy rendszerbe össze lehet vonni ezeket az adatokat:
array(
'action' => array(
'postId' => 'captcha'
)
)
Az összevont adatokat pedig be lehet illeszteni a jogosultság kezelő rendszerbe:
$permissions=array(
'Www' => array(
'Articles' => array(
'read' => true,
'write' => array(
'1fd6b8ee5613' => '1745'
),
'edit' => array(
'e7b2576243d2' => true,
'629b9d7a624f' => true
)
)
)
);
A fentiek alapján a felhasználónak joga van a cikkek olvasásához, írásához és szerkesztéséhez, és éppen egy cikket ír, amire a captcha kód 1745, két cikket pedig szerkeszt, a szerkesztés pedig nem kér captcha kódot.
A rendszert még nem teszteltem élesben, nem tudom, hogy mennyire terheli a rendszert a postId
generálás, viszont ha túlságosan, akkor lehet kombinálni a két CSRF védelmi módszert: a belépéskor generálok egy hosszabb postId
-t, az űrlapok azonosítására pedig csak azoknak a sorszámait használom.
Annyit hozzátennék, hogy a
Szóval mint minden eszközt, ezt is csak ésszel lehet használni. Még épül a rendszer, amibe beteszem ennek a továbbfejlesztett változatát, csak azért tettem ki blogba, hátha lesznek építő jellegű hozzászólások.
Captcha olvasás
a gepi OCR meg nem elegge
"kicsit" elavult, de kiindulasi pontnak jo:
http://caca.zoy.org/wiki/PWNtcha
Tyrael
Hát ez nem egyszerű kérdés,
Nem írtál konkrétumot, hogy milyen űrlapról van szó, úgy általánosságban pár dolgot tudsz szűrni, és meg tudod akadályozni, hogy valaki túl sűrűn küldjön űrlapot, de ezen kívül csak emberi beavatkozással tudod kitiltani a botot az oldalról, meg törölni az addigi tevékenységét.
Annyit tudsz tenni, ha ilyen történik, hogy keresel egy jobb captcha generálót, amit nem törnek fel.
Sokkal egyszerűbb eltárolni
Kifejtenéd? Nem teljesen
Egyirányú hashfüggvény + só,
Konfig fájlban:
Ezzel mindössze annyi a gond,
Szóval sürgősen felejtsd el, hogy captcha ellenőrző kódot akár saltolva is kiteszel bárhova.
Mint írtam, ha nem akarsz minden egyes űrlapot azonosítani, csak crsf védelem kell, akkor elég annyi, hogy minden sessionhöz saját postId-t generáltatsz, és azt kéred vissza minden küldött űrlapnál.
Egy picikét el vagy tévedve a
A példában szereplő 32 karakteres kulcs már bőven túl van a mai számítógépek képességein, arról nem beszélve, hogy a szivárványtábla nagy méreteknél már a véges tárhely miatt nem túl gyors, márpedig a captchatörés tipikusan olyan támadásokhoz kell, ahol a sebesség nagyon számít. (Viszonyításképpen, az Ophcrack egy 8 gigás rainbow táblával tud max 14 karakteres jelszavakat törni, és egy törés percekig tart, ami nagyon jó, ha egy szerverre való betöréshez kell, de ha spammeléshez, akkor már nem annyira.) De ha nagyon paranoid vagy, nyugodtan használhatsz UUID helyett egy ezer karakteres random sztringet.
Hmm, lehet, hogy el vagyok
Egyébként ez egy elv, hogy nem teszem ki visszafejthető formában a captcha kódot, amit kérek. Feleslegesen nem nyitok új támadási pontot. Bőven elég az, hogy a captchat is beolvastathatják, ha rossz a kódja.
Hosszú szövegeket md5-ből
A captchának éppenséggel az a lényege, hogy visszafejthető :) de ettől eltekintve, egy sózott md5-ben semmi visszafejthető nincsen. Ez egy standard biztonságtechnikai módszer, ezt használják jelszavak védelmére, hasonló konstrukció van a HTTPS protokollban, ha szerinted ez támadási pont, akkor valószínűleg nem érted, hogyan működik. Ha valaki rájönne, hogyan törhető az md5 (ami elméletileg persze lehetséges), aligha az lenne az első dolga, hogy szaladjon feltörni a te captchádat.
Az viszont csúnya hiba a
Az elhasznált kulcsok törlése
Szóval ez sem jött be. Ha meg egy kulcsot többször engedélyezel, akkor meg megint az van, mint írtad, hogy végtelenszer beküldhetik ugyanazt.
Annyit lehet csinálni a te módszereddel, hogy generálsz a captcha mellé még egy véletlen string-et, amit visszakérsz az űrlappal. Így meg lehet annyira növelni a variációk számát, hogy szinte nulla legyen az ismétlődés esélye. Aztán így már lehet érvényteleníteni az elhasznált kódokat.
Végülis lehetséges megoldás, de ugyanúgy véletlen azonosító kell minden captchas űrlaphoz, mint annál, amit én írtam. (Én inkább maradok a saját megoldásomnál :-P)
Egyébként ha valaki nagyon
Csak vigyázz, hogy ne ess te
Egyirányú hashfüggvény + só,
Konfig fájlban:
Az egyedi postId másfelől
Na tessék
Ilyen az élet :-)