25. februar 2012 - 22:06Der er
24 kommentarer og 1 løsning
Sessions og sikkerhed?
Hej Eksperter.
Jeg har fået lavet mit login-system, så man både kan registrere sig og logge ind. Nu er jeg så nået til sessionsdelen, og jeg føler mig lidt usikker på hvordan jeg skal bygge det op, og hvilke sikkerhedsmæssige hensyn jeg skal tage.
Så har i nogen råd eller tips, evt. links, som i ville dele med mig?
Sikker database håndtering er et rigtig godt sted at begynde - uagtet, at det for skræmmende mange er uudforsket land.
Håndtering af fejl er ligeledes et ofte overset emne - undtagen af personer med hang til at lægge databaser ned.
Husk også, at du altid bør lægge et lille delay (blot 0.5-1 sekund) ind i din login funktion - hvadenten login lykkes eller ej. Det afholder somregel bøhtosserne fra at fortsætte et bruteforce angreb ud over første eller andet hit.
Men som keysersoze skriver er session theft og XSS (Cross Site Scripting) et par rigtig grimme ting, som kan være vanskelige at overskue. Søg på Google - der burde være millioner af hits på hver.
Alle disse emner er nødvendige at forholde sig til, hvis du vil lave en sikker applikation.
Efter dit svar, sidste gang, er jeg gået over til mysqli og prepare statement, så det skulle være nogen lunde nu. Desuden sletter jeg altid mine fejlmeddelser, når jeg er færdig med debugging, dog vil jeg begynde på dit define('IN_DEBUG_MODE', true);, da det ser yderst lettere ud.
Hmm.. Du skriver at man kunne lægge et delay ind på login-funktionen. Skulle det så være noget lignende at man puttede IP-adressen ind i en tabel, og så lavede noget sleep(1)?
Ja, det er en fin måde at lave det på. Opret en tabel til login forsøg. Så kan du indsætte IP'en sammen med et timestamp - time(). Så kan du teste for, om der har været f.eks. fem forsøg indenfor et kort tidsrum:
$NU = time(); $IP = Bruger IP if (dette femte forsøg fra $IP siden $NU - 10) { Ban $IP; } else { Log $IP med $NU } Slet alle bans, der er ældre end $NU - (60*60); Slet alle IP-logs, der er ældre end $NU - 60;
#6: Så er 'brugeren' banned i en time efter 'forbrydelsen'.
En anden ting er, at bør have flere brugere/passwords til din database. Til de forskellige brugere knytter du så kun de privilegier, der er nødvendige for den brugers rolle.
Er en bruger ikke logget ind, men bare kikker sider, må data kun hentes fra DB'en med den DB-bruger, som kun har lov til at lave SELECT kommandoer.
Har du en side med offentlige kommentarer, må samme bruger både have lov til SELECT og INSERT på den side - og intet andet. Han skal altså logges ind med en anden bruger på den side.
Er brugeren logget ind, logges han ind i DB'en med den DB-bruger, der har de privilegier, som er nødvendige for at kunne bruge den pågældende sides funktionaliteter som hans rolle tillader - og intet andet.
Udviklerens rolle har lov til det hele. Fra og med 'Good Admin' og ned indskrænkes privilegierne.
Alt efter din struktur og kompelksitet, kan du oprette en privilegie tabel og evt. en relateret rolle tabel, så du kan holde styr på, med hvilken DB-bruger, der skal logges ind i databasen, hvor.
At bruge DB-privilegierne i rollestyringen er det sidste, der stopper fækalien, før den rammer ventilatoren! Du skulle gerne have fanget en fejl tidligere, men har 'han' alligevel snydt dig, kan du (forhåbentlig) redde det her.
Er en session stjålet fra den rigtige, banker forsøget dog meget sandsynligt lige igennem. Derfor bør keysersoze lægge svaret for #1, som er enormt vigtigt. Jeg blev vist bare derfra grebet af den gode stemning =)
Så længe du ikke gemmer "vigtige" data i dine sessions er første udfordring løst - men da de data i #16 i teorien kan hijackes er det en god idé som du er inde på i #14 at kunne genkende brugeren på andet end bare et navn og loginstatus, men at benytte HTTP_USER_AGENT giver måske ikke den store mening da flere brugere nok kører med samme setup, så vil fx IP-nummer nok give mere mening.
Så du mener, at man simpelthen kan logge brugerens ip? Altså, sætte ip-adressen ind tabbelen, når brugeren logger ind, og så tjekke om det er den samme ip, når brugeren, så skal et eller andet?
Det var i hvert fald en mulighed - men stadig, er det virkelig vigtige data er eneste vej frem SSL. Så længe du ikke kører SSL kan alle informationer der sendes frem og tilbage læses - også login-oplysninger og har man først fat i dem kan du sikre dig nok så meget med IP-nummer osv.
- men SSL giver ingen sikkerhed i sig selv. Det sørger blot for, at trafikken frem og tilbage er krypteret. Det er skræmmende ofte, man ser applikationer, hvor det f.eks. med lidt injection fiflerier er muligt at få listet andre brugeres loginoplysninger.
Har du en usikker applikation, kan det være ligemeget, om du bruger SSL eller ej. I forbindelse med, hvad jeg tidligere skrev om authorization og authentication, bør du prøve at søge på ACL (Access Control Lists) og RBAC (Role Based Access Control). Det er ikke ukompliceret at skrive en sikker applikation, hvorfor mange da også anvender færdige løsninger til at håndtere authorization og authentication.
Det er i den forbindelse vigtigt, at man både sikrer korrekt adgang til funktionaliteterne i PHP-koden og sikrer korrekt adgang til databasen.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.