Korábbi írásomban az ITSCC 2010 negyedik feladatáról elmélkedtem. Zanzásítva az volt a lényege, hogy írni kell egy dokumentum megosztó web alkalmazást, amely nem védhető szerver konfigurációs trükkökkel, nem használhat adatbázist, és a fájlokat csak a jogosult felhasználók érhetik el. Most egy kicsit a gyakorlati szempontból elemezgetném a megoldásokat. Csapatokat szándékosan nem nevesítek.
Bár a verseny megoldható bármilyen programozási nyelven, ez a feladat könyörög azért, hogy PHP-t használjatok. Titkon erre is számítottam. A J2EE annál igényesebb (hogy ez most jó, vagy nem, abba ne menjünk bele), és komolyabb tervezést igénylő nyelv, hogy ennyi idő alatt értékelhető megoldás szülessen. Egyik csapat C/C++-ban írt webszerverrel (!) próbálkozott, ami elég nagyravágyó törekvés, és esetünkben, teljesen felesleges volt (Ha kötekedni akartam volna, akkor ellentétes a feladatkiírással). Ágyúval verébre lődözés tipikus esete.
Eszembe jut egy érdekes eset! Kikötés volt, hogy nem lehet semmilyen publikus keretrendszert használni, mert nem akartuk túlságosan megkönnyíteni a versenyzők dolgát. Egyik csapat úgy érezte, hogy rés van a pajzson, és bejelentette, hogy ő a saját keretrendszerét használja, amit korábban fejlesztett, és nem nyilvános, tehát nem sérti a kiírást. Azt valóban nem sértette, és nem is kapott érte negatív elbírálást, de a keretrendszer „kicsit” szélesebb körű volt, mint ami a versenyhez szükséges lett volna, és a versenyző nem takarította ki a felesleget. Innen is köszi a rendszert, de ne aggódj nem fogjuk használni, illetve nem tesszük nyilvánossá. ;)
Webalkalmazás kezdőknek kérdéskört továbbra se kívánom feszegetni, ezért most a felhasználók kezelésének a problémakörét fogom elemezgetni.
A felhasználók adatait szinte minden esetben valamilyen fájlban igyekeztek tárolni. Sokan beleestek abba a hibába, hogy azt feltételezték, hogy ha a felhasználó fájlt kívül helyezik a DOCROOTon, akkor minden problémát megoldottak. Így keletkezett például user.txt az alábbi struktúrával:
admin
almafa123
admin@szerver.hu
igen
user
asdf12
uzer@szerver.hu
nem
Nevezzük LBSV (line break separated values) struktúrának. Ebből a szempontból akár életképes is lenne, ha nem társulna hiányos input ellenőrzéssel, ami engedi üres adat bevitelé, és így a kiolvasásnál fel is borul szépen a sorrend. Nem különülnek el egymástól egyértelműen a rekordok, csak az adatok sorszáma alapján. Nincs probléma az LBSVvel, nekem is kellett már hasonlót használni, de az összetartozó adatokat mindenképpen jelezni kell valahogy.
Az, hogy a jelszavak sehogy sincsenek titkosítva pedig egyszerűen nem elfogadható. Egy MD5, vagy SHA1 hash ráfuttatása ujjgyakorlat, és a biztonságot máris fényévekkel megemeli. Igaz ez főleg, ha a fájl még HTTP-vel el is érhető. A titkosítatlan jelszavak még mindig az egyik legnagyobb privacy problémának számítanak a weben.
Kis kitérő, de bosszantóan sok helyen találkoztam azzal a megoldással, hogy bár a jelszó védve volt az adatbázisban, de ugyanabban a táblában volt egy pwdreminder oszlop is, ahol titkosítatlanúl tárolták a jelszót. Nem feltételezhetjük, hogy a támadó (aki lehet rosszindulatú belsős is) nem fog hozzáférni az adatbázisunkhoz, és a felhasználó igen is szokja meg, ha elveszti a jelszavát, akkor a rendszer újat fog generálni. Tipikus esete annak, amikor a programozó, vagy a felhasználó lustasága veszélyezteti a rendszer alapvető biztonságát.
Érthetetlen, hogy miért pazarolt a programozó erőforrást arra, hogy egy booleant igen/nem értékkel mentsen el. Miért kell strcmp-t alkalmazni ott, ahol egy teljesen egyszerű összehasonlítás is elegendő lett volna. Súlyos, és érthetetlen hiba, mégis több helyen láttam ilyet. Az adatfájlokat tipikusan a gép számára készítjük, nem azért, hogy mi a programozók kényelmesebben olvashassuk.
Könnyebben, és biztonságosabban programozható, ha a fájl tartalmát például *NIX userfile struktúrába szervezzük.
admin:447d51f174e77350c26333cffd2b1470b769865d:admin@szerver.hu:1
Itt az adatokat valamilyen speciális karakter (esetünkben ’:’), vagy minta választja el, és a rekordokat pedig az újsor. Ez a karakterlánc nagyon könnyen, és gyorsan bontható, az adatok megbízhatóan feldolgozhatóak, de ez is bukhat elégtelen input ellenőrzésen. Ha engedélyezzük a szeparátor karakter bevitelét, megsüthetjük a logikánkat. Ez ellen persze alkalmazhatunk valami bonyolult elválasztót (’-{#&@@-’), de elegánsabb előfordulását helyettesítő karakterrel megoldani, vagy egyszerűen már a felhasználó felületen kijelenteni, hogy milyenek a nem megfelelő karakterek, és ott elkapni. Ezt olvasva, gondolom, sokan bólogatnak; hogy persze, ez nyilvánvaló, mégis a megoldások során ez bizony sokszor elmaradt. Ez az egyik legismertebb tárolási forma, és ennél nem is kell okosabbnak lenni. Ez persze nem jelenti azt, hogy nem lehetünk.
user:a233f0e898ed0661d6d47ed0958f16b52e537231::0
Még mindig feltételezhetjük, hogy a potenciális támadó képes lehet HTTP-n megszerezni a fájlt, és bár „titkosítottuk” a jelszavat, miért nem nehezítjük meg még jobban a dolgát? Kihasználva a választott nyelv tulajdonságait, adja magát a megoldás, hogy PHP fájlban tároljuk ezeket az adatokat. Még ha közvetlenül is akarja lekérni a felhasználó HTTP-n keresztül, a szerver megteszi nekünk azt a szívességet, hogy „lefuttatja”, és nem lesz kimenete.
Users.php:
<?php die(’LOL :P’);/*Kifinomult megoldas lenne egy Location header kuldese, de igazandibol mindegy*/?>
Lehet ezt még fokozni? De még mennyire. Egyik kedvenc megoldásomban PHP változóként tárolta le a versenyző, ehhez hasonlóan:
admin:447d51f174e77350c26333cffd2b1470b769865d:admin@szerver.hu::1
user:a233f0e898ed0661d6d47ed0958f16b52e537231::0
$users[]=array(’admin’,’447d51f174e77350c26333cffd2b1470b769865d’,’admin@szerver.hu’,’1’);
Elmés kihasználása a szkript nyelvek sajátosságának, hogy on-demand áll elő a futtatott kód, amúgy meg csak egy szövegfájl, amit írhatunk. Ezt már csak include-olni kell, és probléma letudva.
Elmélkedhetnénk még a jelszavak védelméről, illetve még rafináltabb megoldásokról a felhasználói adatok tárolására, de ez már rád vár, itt alul, a kommentek közt. Legközelebb azt nézem meg, hogy oldották meg a versenyzők a dokumentumok védelmét.
Jelszókezelés? Mi sem egyszerűbb.
2011.02.22. 12:02 | Alice és Udi | Szólj hozzá!
Címkék: verseny programozás itscc2010 felhasználókezelés
A bejegyzés trackback címe:
https://aliceesbob.blog.hu/api/trackback/id/tr192679316
Kommentek:
A hozzászólások a vonatkozó jogszabályok értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a Felhasználási feltételekben és az adatvédelmi tájékoztatóban.
Nincsenek hozzászólások.