De definitieve gids voor formuliergebaseerde websiteauthenticatie

Form-based authenticatie voor websites

Wij geloven dat Stack Overflow niet alleen een bron zou moeten zijn voor zeer specifieke technische vragen, maar ook voor algemene richtlijnen over hoe variaties op veelvoorkomende problemen op te lossen. "Form-based authentication for websites" zou een prima onderwerp moeten zijn voor zo'n experiment.

Het zou onderwerpen moeten bevatten zoals:

  • Hoe in te loggen
  • Hoe uitloggen
  • Hoe ingelogd blijven
  • Cookies beheren (inclusief aanbevolen instellingen)
  • SSL/HTTPS encryptie
  • Hoe wachtwoorden op te slaan
  • Geheime vragen gebruiken
  • Vergeten gebruikersnaam/wachtwoord functionaliteit
  • Gebruik van nonces om cross-site request forgeries (CSRF) te voorkomen
  • OpenID
  • "Onthoud mij" selectievakje
  • Browser autocompletie van gebruikersnamen en wachtwoorden
  • Geheime URL's (openbare URL beschermd door digest)
  • Controle van wachtwoordsterkte
  • E-mail validatie
  • en nog veel meer over formuliergebaseerde authenticatie...

Het zou geen dingen moeten bevatten zoals:

  • Rollen en autorisatie
  • HTTP basis authenticatie

Help ons alstublieft door:

  1. Subonderwerpen voor te stellen
  2. Goede artikelen over dit onderwerp in te zenden
  3. Bewerken van het officiële antwoord
Oplossing

DEEL I: Hoe in te loggen

We'nemen aan dat je al weet hoe je een login+wachtwoord HTML formulier bouwt dat de waarden POST naar een script aan de server kant voor authenticatie. De secties hieronder zullen gaan over patronen voor goede praktische auth, en hoe je de meest voorkomende veiligheids valkuilen kunt vermijden. *To HTTPS or not to HTTPS? Tenzij de verbinding al beveiligd is (dat wil zeggen, getunneld door HTTPS met behulp van SSL / TLS), zal uw login-formulier waarden worden verzonden in duidelijke tekst, waardoor iedereen die afluistert op de lijn tussen browser en webserver in staat zal zijn om logins te lezen als ze passeren. Dit soort afluisteren wordt routinematig gedaan door overheden, maar in het algemeen zullen we'niet ingaan op 'owned' afluisterpraktijken anders dan dit te zeggen: Gebruik gewoon HTTPS. In essentie is de enige praktische* manier om je te beschermen tegen afluisteren/packet sniffing tijdens het inloggen door gebruik te maken van HTTPS of een ander certificaat-gebaseerd encryptie schema (bijvoorbeeld, [TLS][1]) of een bewezen & getest challenge-response schema (bijvoorbeeld, het [Diffie-Hellman][2]-gebaseerde SRP). Elke andere methode kan gemakkelijk omzeild worden door een afluisterende aanvaller. Natuurlijk, als je bereid bent om een beetje onpraktisch te worden, zou je ook een vorm van twee-factor authenticatie kunnen gebruiken (b.v. de Google Authenticator app, een fysiek 'cold war style' codeboek, of een RSA sleutelgenerator dongle). Indien correct toegepast, zou dit zelfs kunnen werken met een onbeveiligde verbinding, maar het is moeilijk voor te stellen dat een ontwikkelaar bereid zou zijn om twee-factor auth te implementeren maar geen SSL. (Niet) Roll-your-own JavaScript encryptie/hashing Gezien de waargenomen (hoewel nu [vermijdbaar][27]) kosten en technische moeilijkheid van het opzetten van een SSL-certificaat op uw website, komen sommige ontwikkelaars in de verleiding om hun eigen hashing- of encryptieschema's in de browser te gebruiken om te vermijden dat logins in klare tekst over een onbeveiligde draad worden doorgegeven. Hoewel dit een nobele gedachte is, is het in wezen nutteloos (en kan het een [veiligheidsfout][3] zijn) tenzij het wordt gecombineerd met een van de bovenstaande - dat wil zeggen, ofwel het beveiligen van de lijn met sterke encryptie of het gebruik van een beproefd challenge-response mechanisme (als je niet weet wat dat is, weet dan dat het een van de moeilijkst te bewijzen, moeilijkst te ontwerpen, en moeilijkst te implementeren concepten in digitale veiligheid is). Hoewel het hashen van het wachtwoord effectief kan zijn tegen wachtwoordopenbaarmaking, is het kwetsbaar voor replay-aanvallen, Man-In-The-Middle-aanvallen / hijackings (als een aanvaller een paar bytes in uw onbeveiligde HTML-pagina kan injecteren voordat deze uw browser bereikt, kunnen ze eenvoudigweg de hashing in het JavaScript uitcommentariëren), of brute-force-aanvallen (aangezien u de aanvaller zowel gebruikersnaam, zout als het gehashte wachtwoord geeft). CAPTCHAS tegen de mensheid [CAPTCHA][4] is bedoeld om één specifieke aanvalscategorie tegen te gaan: geautomatiseerde dictionary/brute force trial-and-error zonder menselijke operator. Er is geen twijfel dat dit een reële bedreiging is, echter, er zijn manieren om er naadloos mee om te gaan die geen CAPTCHA vereisen, specifiek goed ontworpen server-side login throttling schema's - we'zullen die later bespreken. Weet dat CAPTCHA implementaties niet gelijk geschapen zijn; ze zijn vaak'niet door mensen op te lossen, de meeste zijn eigenlijk ineffectief tegen bots, ze zijn allemaal ineffectief tegen goedkope derde-wereld arbeid (volgens [OWASP][5], is het huidige sweatshop tarief $12 per 500 tests), en sommige implementaties kunnen technisch illegaal zijn in sommige landen (zie [OWASP Authentication Cheat Sheet][6]). Als u een CAPTCHA moet gebruiken, gebruik dan Google's [reCAPTCHA][7], omdat het per definitie OCR-hard is (omdat het reeds OCR-geclassificeerde boekscans gebruikt) en erg zijn best doet om gebruikersvriendelijk te zijn. Persoonlijk vind ik CAPTCHAS vervelend, en gebruik ik ze alleen als laatste redmiddel wanneer een gebruiker er een aantal keren niet in geslaagd is in te loggen en de vertragingen maximaal zijn. Dit zal zelden genoeg gebeuren om aanvaardbaar te zijn, en het versterkt het systeem in zijn geheel. Het opslaan van wachtwoorden / verifiëren van logins Dit mag dan eindelijk algemeen bekend zijn na alle geruchtmakende hacks en lekken van gebruikersgegevens die we de afgelopen jaren hebben gezien, maar het moet gezegd worden: Sla wachtwoorden niet in duidelijke tekst op in uw database. Gebruikersdatabases worden routinematig gehackt, gelekt of ontfutseld via SQL-injectie, en als u ruwe, onversleutelde wachtwoorden opslaat, is dat meteen einde verhaal voor uw aanmeldingsbeveiliging. Dus als je het wachtwoord niet kunt opslaan, hoe controleer je dan dat de login+wachtwoord combinatie POSTed van het loginformulier correct is? Het antwoord is hashing met behulp van een [sleutelafleidingsfunctie][24]. Telkens wanneer een nieuwe gebruiker wordt aangemaakt of een wachtwoord wordt gewijzigd, neemt u het wachtwoord en voert het door een KDF, zoals Argon2, bcrypt, scrypt of PBKDF2, waardoor het klare wachtwoord ("correcthorsebatterystaple") wordt omgezet in een lange, willekeurig uitziende string, die een stuk veiliger is om in uw database op te slaan. Om een login te verifiëren, voert u dezelfde hash-functie uit op het ingevoerde wachtwoord, deze keer met de salt en vergelijkt u de resulterende hash-string met de waarde die in uw database is opgeslagen. Argon2, bcrypt en scrypt slaan het zout al met de hash op. Bekijk dit [artikel][23] op sec.stackexchange voor meer gedetailleerde informatie. De reden dat een zout wordt gebruikt is dat hashing op zichzelf niet voldoende is -- u'zult een zogenaamd 'salt' willen toevoegen om de hash te beschermen tegen [rainbow tables][8]. Een zout voorkomt effectief dat twee wachtwoorden die precies overeenkomen worden opgeslagen als dezelfde hashwaarde, waardoor wordt voorkomen dat de hele database in één keer wordt gescand als een aanvaller een wachtwoord-raad-aanval uitvoert. Een cryptografische hash mag niet worden gebruikt voor de opslag van wachtwoorden, omdat door de gebruiker gekozen wachtwoorden niet sterk genoeg zijn (d.w.z. meestal niet genoeg entropie bevatten) en een aanvaller met toegang tot de hashes een aanval om wachtwoorden te raden in relatief korte tijd zou kunnen uitvoeren. Daarom worden KDF's gebruikt - deze ["stretch the key"][25], wat betekent dat elke keer dat een aanvaller een wachtwoord raadt, dit leidt tot meerdere herhalingen van het hash-algoritme, bijvoorbeeld 10.000 keer, waardoor de aanvaller het wachtwoord 10.000 keer langzamer raadt. Sessiegegevens - "U bent ingelogd als Spiderman69"** Zodra de server de login en het wachtwoord heeft geverifieerd met uw gebruikersdatabase en een overeenkomst heeft gevonden, heeft het systeem een manier nodig om te onthouden dat de browser is geauthenticeerd. Dit feit moet alleen worden opgeslagen op de server in de sessie gegevens.

Als je niet bekend bent met sessie data, dit is hoe het werkt: Een enkele willekeurig gegenereerde string wordt opgeslagen in een aflopende cookie en gebruikt om te verwijzen naar een verzameling gegevens - de sessiegegevens - die op de server is opgeslagen. Als u een MVC-framework gebruikt, wordt dit ongetwijfeld al afgehandeld. Als het enigszins mogelijk is, zorg er dan voor dat de sessiecookie de secure en HTTP Only vlaggen aan heeft staan wanneer hij naar de browser wordt gestuurd. De vlag HttpOnly biedt enige bescherming tegen het lezen van de cookie via een XSS-aanval. De vlag secure zorgt ervoor dat de cookie alleen via HTTPS wordt teruggestuurd, en beschermt dus tegen netwerksnuffelaanvallen. De waarde van de cookie mag niet voorspelbaar zijn. Wanneer een cookie wordt aangeboden dat verwijst naar een niet-bestaande sessie, moet de waarde ervan onmiddellijk worden vervangen om session fixation te voorkomen.

DEEL II: Hoe ingelogd blijven - De beruchte "Remember Me" Checkbox

Persistent Login Cookies ("remember me" functionaliteit) zijn een gevarenzone; aan de ene kant zijn ze net zo veilig als conventionele logins als gebruikers begrijpen hoe ze ermee om moeten gaan; en aan de andere kant zijn ze een enorm veiligheidsrisico in de handen van onvoorzichtige gebruikers, die ze misschien op openbare computers gebruiken en vergeten uit te loggen, en die misschien niet weten wat browsercookies zijn of hoe ze verwijderd moeten worden. Persoonlijk hou ik van persistente logins voor de websites die ik regelmatig bezoek, maar ik weet hoe ik ze veilig kan gebruiken. Als je er zeker van bent dat je gebruikers hetzelfde weten, kun je persistente logins gebruiken met een schoon geweten. Zo niet - wel, dan kunt u de filosofie onderschrijven dat gebruikers die onzorgvuldig zijn met hun inloggegevens het over zichzelf hebben afgeroepen als ze gehackt worden. Het is ook niet zo dat we naar de huizen van onze gebruikers gaan om al die Post-It briefjes met wachtwoorden die ze op de rand van hun beeldschermen hebben liggen, eraf te rukken. Natuurlijk kunnen sommige systemen het zich niet veroorloven dat alle accounts gehackt worden; voor zulke systemen is het niet te rechtvaardigen om persistente logins te hebben. Als u besluit om persistente login cookies te implementeren, dan doet u dat als volgt:

  1. Ten eerste, neem wat tijd om Paragon Initiative's artikel over het onderwerp te lezen. U'll moet een heleboel elementen goed te krijgen, en het artikel doet een groot werk van de uitleg van elk.
  2. En om een van de meest voorkomende valkuilen te herhalen, BESLAG DE PERSISTENT LOGIN COOKIE (TOKEN) NIET IN JE DATABASE, ALLEEN EEN HASH VAN HET! Het login token is Password Equivalent, dus als een aanvaller je database in handen zou krijgen, zouden ze de tokens kunnen gebruiken om in te loggen op elk account, net alsof het cleartext login-paswoord combinaties zijn. Gebruik daarom hashing (volgens https://security.stackexchange.com/a/63438/5002 is een zwakke hash prima voor dit doel) bij het opslaan van persistente login tokens.

    DEEL III: Geheime vragen gebruiken

    Don't implementeer 'geheime vragen'. De 'geheime vragen'-functie is een beveiligingsantipatroon. Lees de paper van link nummer 4 van de MUST-READ lijst. U kunt Sarah Palin vragen over die ene, nadat haar Yahoo! e-mail account werd gehackt tijdens een vorige presidentiële campagne, omdat het antwoord op haar veiligheidsvraag was ... "Wasilla High School"! Zelfs met door de gebruiker gespecificeerde vragen, is het zeer waarschijnlijk dat de meeste gebruikers een van beide zullen kiezen:

  • Een standaard geheime vraag, zoals moeders meisjesnaam of favoriete huisdier.
  • Een eenvoudig stukje trivia dat iedereen van zijn blog, LinkedIn profiel, of iets dergelijks kan halen
  • Elke vraag die makkelijker te beantwoorden is dan het raden van hun wachtwoord. Wat, voor elk fatsoenlijk wachtwoord, elke vraag is die je je kunt voorstellen Tot slot zijn beveiligingsvragen inherent onveilig in vrijwel al hun vormen en variaties, en mogen ze om geen enkele reden worden gebruikt in een verificatieschema. De ware reden waarom beveiligingsvragen zelfs maar in het wild bestaan is dat ze handig de kosten besparen van een paar support telefoontjes van gebruikers die'geen toegang kunnen krijgen tot hun e-mail om aan een reactiveringscode te komen. Dit ten koste van de veiligheid en Sarah Palin's reputatie. De moeite waard? Waarschijnlijk niet.

    DEEL IV: Wachtwoord vergeten functionaliteit

    Ik heb al gezegd waarom je nooit beveiligingsvragen moet gebruiken voor het afhandelen van vergeten/verloren gebruikerswachtwoorden; het spreekt ook voor zich dat je gebruikers nooit hun werkelijke wachtwoorden moet e-mailen. Er zijn nog minstens twee veel voorkomende valkuilen die je op dit gebied moet vermijden:

  1. Stel een vergeten wachtwoord niet her in op een automatisch gegenereerd sterk wachtwoord - zulke wachtwoorden zijn notoir moeilijk te onthouden, wat betekent dat de gebruiker het moet veranderen of opschrijven - zeg, op een knalgele Post-It op de rand van hun monitor. In plaats van een nieuw wachtwoord in te stellen, laat u gebruikers gewoon meteen een nieuw wachtwoord kiezen - wat ze toch al willen doen. (Een uitzondering hierop zou kunnen zijn als de gebruikers universeel een wachtwoordmanager gebruiken om wachtwoorden op te slaan/te beheren die normaal gesproken onmogelijk te onthouden zijn zonder het op te schrijven).
  2. Hash altijd de verloren wachtwoord code/token in de database. AGAIN, deze code is een ander voorbeeld van een Password Equivalent, dus het MOET gehasht worden voor het geval een aanvaller uw database in handen krijgt. Wanneer een verloren wachtwoord code wordt opgevraagd, stuur de platte tekst code naar de gebruiker's e-mail adres, hash het dan, sla de hash op in uw database -- en gooi het origineel weg. Net als een wachtwoord of een persistent login token. Een laatste opmerking: zorg er altijd voor dat je interface voor het invoeren van de 'lost password code' minstens zo veilig is als je login formulier zelf, of een aanvaller zal dit gewoon gebruiken om toegang te krijgen. Ervoor zorgen dat u zeer lange 'lost password codes' genereert (bijvoorbeeld 16 hoofdlettergevoelige alfanumerieke karakters) is een goed begin, maar overweeg dezelfde throttling regeling toe te voegen die u voor het loginformulier zelf doet.

    DEEL V: De sterkte van wachtwoorden controleren

    Ten eerste, wil je dit kleine artikel lezen voor een reality check: De 500 meest voorkomende wachtwoorden Oké, dus misschien is de lijst niet de canonieke lijst van meest voorkomende wachtwoorden op een systeem overal ooit, maar het'is een goede indicatie van hoe slecht mensen hun wachtwoorden zullen kiezen wanneer er geen afgedwongen beleid is. Plus, de lijst lijkt beangstigend dicht bij huis als je hem vergelijkt met openbaar beschikbare analyses van recent gestolen wachtwoorden. Dus: Zonder minimum eisen voor de sterkte van wachtwoorden, gebruikt 2% van de gebruikers een van de top 20 meest voorkomende wachtwoorden. Dat betekent: als een aanvaller maar 20 pogingen krijgt, zal 1 op de 50 accounts op uw website te kraken zijn. Om dit te voorkomen moet de entropie van een wachtwoord worden berekend en vervolgens een drempelwaarde worden toegepast. Het National Institute of Standards and Technology (NIST) Special Publication 800-63 heeft een aantal zeer goede suggesties. Dat, wanneer gecombineerd met een woordenboek en toetsenbordindeling analyse (bijvoorbeeld, 'qwertyuiop' is een slecht wachtwoord), kan 99% van alle slecht gekozen wachtwoorden afwijzen op een niveau van 18 bits van entropie. Simpelweg de wachtwoordsterkte berekenen en een visuele sterktemeter tonen aan een gebruiker is goed, maar onvoldoende. Tenzij het wordt afgedwongen, zullen veel gebruikers het zeer waarschijnlijk negeren. En voor een verfrissende kijk op de gebruiksvriendelijkheid van wachtwoorden met hogeentropie, is Randall Munroe's Password Strength xkcd een aanrader. Gebruik Troy Hunt's Have I Been Pwned API om wachtwoorden van gebruikers te vergelijken met wachtwoorden die gecompromitteerd zijn in openbare datalekken.

    DEEL VI: Veel meer - Of: Het voorkomen van snelvuur inlogpogingen

    Kijk eerst eens naar de cijfers: Password Recovery Speeds - How long will your password stand up Als je'geen tijd hebt om de tabellen in die link door te kijken, hier'is de lijst ervan:

  3. Het kost virtueel geen tijd om een zwak wachtwoord te kraken, zelfs als je'het kraakt met een telraam
  4. Het kost vrijwel geen tijd om een alfanumeriek wachtwoord van 9 tekens te kraken als het kastkast ongevoelig is
  5. Het kost vrijwel geen tijd om een ingewikkeld, symbolen-en-letters-en-nummers, hoofd- en kleine letters wachtwoord te kraken als het minder dan 8 tekens lang is (een desktop PC kan het hele toetsenveld tot 7 tekens in een kwestie van dagen of zelfs uren doorzoeken)
  6. *Het zou echter buitensporig veel tijd kosten om zelfs een wachtwoord van 6 tekens te kraken, als je beperkt was tot één poging per seconde! Dus wat kunnen we leren van deze getallen? Nou, veel, maar we kunnen ons richten op het belangrijkste deel: het feit dat het voorkomen van grote aantallen snelvuur opeenvolgende inlogpogingen (dat wil zeggen de brute force aanval) echt niet zo moeilijk is. Maar het juist voorkomen is niet zo eenvoudig als het lijkt. In het algemeen heb je drie keuzes die allemaal effectief zijn tegen brute-force aanvallen (en woordenboekaanvallen, maar aangezien je al een sterk wachtwoordbeleid hanteert, zouden die geen probleem moeten zijn):
  • Een CAPTCHA presenteren na N mislukte pogingen (irritant als de hel en vaak ineffectief -- maar ik'm herhaal mezelf hier)
  • Accounts blokkeren** en e-mailverificatie eisen na N mislukte pogingen (dit is een DoS aanval die erop wacht om te gebeuren)
  • En tot slot login throttling: dat wil zeggen, een tijdvertraging instellen tussen pogingen na N mislukte pogingen (ja, DoS-aanvallen zijn nog steeds mogelijk, maar ze zijn in ieder geval veel minder waarschijnlijk en een stuk ingewikkelder uit te voeren). Best practice #1: Een korte vertraging die toeneemt met het aantal mislukte pogingen, zoals:
  • 1 mislukte poging = geen vertraging
  • 2 mislukte pogingen = 2 seconden vertraging
  • 3 mislukte pogingen = 4 seconden vertraging
  • 4 mislukte pogingen = 8 seconden vertraging
  • 5 mislukte pogingen = 16 seconden vertraging
  • enz. DoS aanvallen op deze regeling zou zeer onpraktisch zijn, aangezien de resulterende vergrendelingstijd iets groter is dan de som van de vorige vergrendelingstijden. Ter verduidelijking: De vertraging is niet een vertraging voor het terugsturen van het antwoord naar de browser. Het is meer een time-out of afkoelingsperiode waarin aanmeldingspogingen voor een specifieke account of vanaf een specifiek IP-adres helemaal niet worden geaccepteerd of geëvalueerd. Dat wil zeggen, correcte inloggegevens zullen niet terugkeren in een succesvolle login, en incorrecte inloggegevens zullen niet leiden tot een vertragingstoename. Best practice #2: Een gemiddelde tijdsvertraging die in werking treedt na N mislukte pogingen, zoals:
  • 1-4 mislukte pogingen = geen vertraging
  • 5 mislukte pogingen = 15-30 minuten vertraging Een DoS-aanval op dit schema zou vrij onpraktisch zijn, maar zeker uitvoerbaar. Het kan ook relevant zijn om op te merken dat zo'n lange vertraging erg vervelend kan zijn voor een legitieme gebruiker. Vergeetachtige gebruikers zullen je niet mogen. **Beste praktijk #3: Combineer de twee benaderingen - ofwel een vaste, korte vertraging die in werking treedt na N mislukte pogingen, zoals:
  • 1-4 mislukte pogingen = geen vertraging
  • 5+ mislukte pogingen = 20 seconden vertraging Of een oplopende vertraging met een vaste bovengrens, zoals:
  • 1 mislukte poging = 5 seconden vertraging
  • 2 mislukte pogingen = 15 seconden vertraging
  • 3+ mislukte pogingen = 45 seconden vertraging Dit laatste schema is afkomstig van de OWASP best-practices suggesties (link 1 van de MUST-READ lijst) en zou als best-practice moeten worden beschouwd, ook al is het toegegeven aan de restrictieve kant. Als vuistregel zou ik echter zeggen: hoe sterker je wachtwoordbeleid is, hoe minder je gebruikers hoeft lastig te vallen met vertragingen. Als u sterke (hoofdlettergevoelige alfanumerieke tekens + verplichte cijfers en symbolen) wachtwoorden van meer dan 9 tekens vereist, zou u de gebruikers 2-4 niet-vertraagde wachtwoordpogingen kunnen geven voordat u de throttling activeert. DoS aanvallen op deze laatste login throttling regeling zou zeer onpraktisch zijn. En als laatste, laat altijd persistente (cookie) logins (en/of een CAPTCHA geverifieerd login formulier) door, zodat legitieme gebruikers niet eens vertraagd worden terwijl de aanval bezig is. Op die manier wordt de zeer onpraktische DoS-aanval een extreem onpraktische aanval. Bovendien is het zinvol om meer agressieve throttling op admin accounts uit te voeren, omdat dat de meest aantrekkelijke ingangspunten zijn

    DEEL VII: Gedistribueerde brute kracht aanvallen.

    Even terzijde, meer geavanceerde aanvallers zullen proberen om login throttling te omzeilen door 'hun activiteiten te verspreiden':

  • Verspreiden van de pogingen op een botnet om IP adres markering te voorkomen
  • In plaats van één gebruiker te kiezen en de 50.000 meest voorkomende wachtwoorden te proberen (wat ze niet kunnen, vanwege onze beperking), zullen ze HET meest voorkomende wachtwoord kiezen en het in plaats daarvan tegen 50.000 gebruikers proberen. Op die manier omzeilen ze niet alleen maximum-pogingen maatregelen zoals CAPTCHAs en login throttling, hun kans op succes neemt ook toe, omdat de nummer 1 meest voorkomende wachtwoord veel waarschijnlijker is dan nummer 49.995
  • Het spreiden van de login verzoeken voor elke gebruikersaccount, zeg, 30 seconden uit elkaar, om onder de radar uit te komen Hier zou de beste praktijk zijn het aantal mislukte logins bij te houden, voor het hele systeem, en een lopend gemiddelde van uw site's bad-login frequentie te gebruiken als basis voor een bovengrens die u dan oplegt aan alle gebruikers. Te abstract? Laat ik het anders formuleren: Stel dat uw site de afgelopen 3 maanden een gemiddelde van 120 bad-logins per dag had. Met dat (lopend gemiddelde), zou je systeem de globale limiet op 3 keer dat kunnen zetten -- dat wil zeggen 360 mislukte pogingen over een periode van 24 uur. Dan, als het totaal aantal mislukte pogingen over alle accounts dat aantal overschrijdt binnen één dag (of nog beter, de snelheid van versnelling monitoren en triggeren op een berekende drempel), activeert het systeembrede login throttling - wat korte vertragingen betekent voor ALLE gebruikers (nog steeds, met uitzondering van cookie logins en/of back-up CAPTCHA logins). Ik heb ook een vraag gepost met meer details en een echt goede discussie over hoe lastige valkuilen te vermijden in het afweren van gedistribueerde brute kracht aanvallen

    DEEL VIII: Twee-factor authenticatie en authenticatieproviders

    Credentials kunnen worden gecompromitteerd, hetzij door exploits, wachtwoorden die worden opgeschreven en verloren, laptops met sleutels die worden gestolen, of gebruikers die logins invoeren op phishing sites. Logins kunnen verder worden beschermd met twee-factorauthenticatie, waarbij gebruik wordt gemaakt van out-of-bandfactoren zoals codes voor eenmalig gebruik die worden ontvangen via een telefoongesprek, sms-bericht, app of dongle. Verschillende providers bieden authenticatiediensten met twee factoren aan. Authenticatie kan volledig worden gedelegeerd naar een single-sign-on dienst, waarbij een andere provider zorgt voor het verzamelen van inloggegevens. Dit legt het probleem bij een vertrouwde derde partij. Google en Twitter bieden beide op standaarden gebaseerde SSO-diensten aan, terwijl Facebook een soortgelijke eigen oplossing biedt.

    MOET-READ LINKS Over Web Authenticatie

  1. OWASP Guide To Authentication / OWASP Authentication Cheat Sheet
  2. Dos and Don'ts of Client Authentication on the Web (zeer leesbaar MIT research paper)
  3. Wikipedia: HTTP cookie
  4. Persoonlijke kennisvragen voor fallback authenticatie: Security questions in the era of Facebook (zeer leesbaar Berkeley research paper)
Commentaren (70)

Definitief Artikel

Verzend referenties

De enige praktische manier om referenties 100% veilig te versturen is door gebruik te maken van [SSL][1]. Het gebruik van JavaScript om het wachtwoord te hashen is niet veilig. Veel voorkomende valkuilen voor client-side wachtwoord hashing:

  • Als de verbinding tussen de client en de server niet versleuteld is, is alles wat je doet [kwetsbaar voor man-in-the-middle aanvallen][2]. Een aanvaller zou het inkomende javascript kunnen vervangen om de hashing te breken of alle credentials naar zijn server kunnen sturen, hij zou kunnen luisteren naar de antwoorden van de client en zich perfect kunnen voordoen als de gebruiker, enz. enz. SSL met vertrouwde certificeringsinstanties is ontworpen om MitM-aanvallen te voorkomen.
  • Het gehashte wachtwoord dat de server ontvangt is [minder veilig][3] als je'geen extra, overbodig werk op de server doet. Er'is een andere veilige methode genaamd SRP, maar het'is gepatenteerd (hoewel het [vrij gelicenseerd][4] is) en er zijn weinig goede implementaties beschikbaar.

    Het opslaan van wachtwoorden

    Sla nooit wachtwoorden op als platte tekst in de database. Zelfs niet als u niet geeft om de veiligheid van uw eigen site. Ga ervan uit dat sommige van uw gebruikers het wachtwoord van hun online bankrekening zullen hergebruiken. Dus, sla het gehashte wachtwoord op, en gooi het origineel weg. En zorg ervoor dat het wachtwoord niet opduikt in toegangslogs of toepassingslogs. OWASP beveelt het gebruik van Argon2 aan als eerste keuze voor nieuwe applicaties. Als dit niet beschikbaar is, moet in plaats daarvan PBKDF2 of scrypt worden gebruikt. En tenslotte, als geen van bovenstaande beschikbaar is, gebruik dan bcrypt. Hashes op zichzelf zijn ook onveilig. Bijvoorbeeld, identieke wachtwoorden betekenen identieke hashes--dit maakt hash lookup tables een effectieve manier om veel wachtwoorden in een keer te kraken. Sla in plaats daarvan de gesaldeerde hash op. Een zout is een tekenreeks die aan het wachtwoord wordt toegevoegd voor het hashen - gebruik een ander (willekeurig) zout per gebruiker. De salt is een publieke waarde, dus u kunt ze samen met de hash in de database opslaan. Zie hier voor meer hierover. Dit betekent dat je'niet hun vergeten wachtwoorden naar de gebruiker kunt sturen (omdat je alleen de hash hebt). Reset het wachtwoord van de gebruiker niet tenzij u de gebruiker hebt geauthenticeerd (gebruikers moeten bewijzen dat ze in staat zijn om e-mails te lezen die naar het opgeslagen (en gevalideerde) e-mailadres zijn verzonden).

    Beveiligingsvragen

    Veiligheidsvragen zijn onveilig - vermijd het gebruik ervan. Waarom? Alles wat een beveiligingsvraag doet, doet een wachtwoord beter. Lees DEEL III: Geheime vragen gebruiken in [@Jens Roland antwoord][6] hier in deze wiki.

    Sessie-cookies

    Nadat de gebruiker inlogt, stuurt de server de gebruiker een sessie cookie. De server kan de gebruikersnaam of id uit de cookie halen, maar niemand anders kan zo'n cookie genereren (TODO leg mechanismen uit). [Cookies kunnen worden gekaapt][7]: ze zijn slechts zo veilig als de rest van de machine van de client's en andere communicatie. Ze kunnen van schijf worden gelezen, in netwerkverkeer worden gesnuffeld, door een cross-site scripting aanval worden gelicht, via een vergiftigde DNS worden gephisht zodat de client zijn cookies naar de verkeerde servers stuurt. Stuur geen persistente cookies. Cookies moeten verlopen aan het einde van de client sessie (browser sluiten of uw domein verlaten). Als u uw gebruikers wilt autologineren, kunt u een persistent cookie instellen, maar het moet verschillend zijn van een full-session cookie. Je kunt een extra vlag instellen die aangeeft dat de gebruiker automatisch is ingelogd, en echt moet inloggen voor gevoelige operaties. Dit is populair bij winkelsites die u een naadloze, gepersonaliseerde winkelervaring willen bieden maar toch uw financiële gegevens willen beschermen. Bijvoorbeeld, wanneer u terugkeert om Amazon te bezoeken, tonen zij u een pagina die eruit ziet alsof u'bent ingelogd, maar wanneer u een bestelling gaat plaatsen (of uw verzendadres, kredietkaart enz. wijzigt), vragen zij u om uw wachtwoord te bevestigen. Financiële websites, zoals banken en creditcards, hebben daarentegen alleen gevoelige gegevens en zouden geen auto-login of een laagbeveiligde modus moeten toestaan.

    Lijst van externe bronnen

Commentaren (5)

Ten eerste, een sterk voorbehoud dat dit antwoord niet het beste is voor deze exacte vraag. Het moet zeker niet het beste antwoord zijn!

Ik zal Mozilla's voorgestelde BrowserID (of misschien meer precies, het Verified Email Protocol) gaan noemen in de geest van het vinden van een upgrade pad naar betere benaderingen van authenticatie in de toekomst.

Ik zal het zo samenvatten:

  1. Mozilla is een non-profitorganisatie met waarden die goed passen bij het vinden van goede oplossingen voor dit probleem.
  2. De realiteit vandaag is dat de meeste websites formulier-gebaseerde authenticatie gebruiken
  3. Formuliergebaseerde authenticatie heeft een groot nadeel, namelijk een verhoogd risico op phishing. Gebruikers wordt gevraagd gevoelige informatie in te voeren in een gebied dat wordt gecontroleerd door een externe entiteit, in plaats van een gebied dat wordt gecontroleerd door hun User Agent (browser).
  4. Aangezien browsers impliciet worden vertrouwd (het hele idee van een User Agent is om namens de gebruiker op te treden), kunnen zij helpen deze situatie te verbeteren.
  5. De voornaamste kracht die hier vooruitgang in de weg staat, is implementatieblokkade. Oplossingen moeten worden onderverdeeld in stappen die op zichzelf al enig incrementeel voordeel opleveren.
  6. De eenvoudigste gedecentraliseerde methode voor het uitdrukken van een identiteit die is ingebouwd in de internetinfrastructuur is de domeinnaam.
  7. Als tweede niveau van identiteitsuitdrukking beheert elk domein zijn eigen set van accounts.
  8. De vorm "account@domain" is beknopt en wordt ondersteund door een breed scala van protocollen en URI-schema's. Een dergelijke identifier wordt natuurlijk het meest universeel herkend als een e-mailadres.
  9. E-mailproviders zijn nu al de de-facto primaire identiteitsverstrekkers online. Met de huidige wachtwoordresetstromen kun je meestal de controle over een account overnemen als je kunt bewijzen dat je het bijbehorende e-mailadres van die account beheert.
  10. Het Verified Email Protocol is voorgesteld om een veilige methode te bieden, gebaseerd op cryptografie met openbare sleutel, voor het stroomlijnen van het proces om aan domein B te bewijzen dat je een account hebt op domein A.
  11. Voor browsers die het Verified Email Protocol niet ondersteunen (momenteel alle), biedt Mozilla een shim die het protocol implementeert in client-side JavaScript code.
  12. Voor e-maildiensten die het Verified Email Protocol niet ondersteunen, staat het protocol derden toe om als vertrouwde tussenpersoon op te treden en te beweren dat zij het eigendom van een account van een gebruiker hebben geverifieerd. Het is niet wenselijk een groot aantal van dergelijke derden te hebben; deze mogelijkheid is alleen bedoeld om een upgradepad mogelijk te maken, en het heeft sterk de voorkeur dat e-maildiensten deze verklaringen zelf verschaffen.
  13. Mozilla biedt zijn eigen dienst aan om als zo'n vertrouwde derde partij op te treden. Dienstverleners (dat wil zeggen, Betrouwbare Partijen) die het Verified Email Protocol implementeren kunnen ervoor kiezen om de beweringen van Mozilla al dan niet te vertrouwen. De dienst van Mozilla verifieert het accounteigendom van gebruikers met de conventionele methode van het verzenden van een e-mail met een bevestigingslink.
  14. Dienstverleners kunnen dit protocol natuurlijk als optie aanbieden naast enige andere methode(n) van authenticatie die zij zouden willen aanbieden.
  15. Een groot voordeel voor de gebruikersinterface dat hier wordt nagestreefd, is de "identiteitsselector". Wanneer een gebruiker een site bezoekt en ervoor kiest zich te authenticeren, toont zijn browser hem een selectie van e-mailadressen ("persoonlijk", "werk", "politiek activisme", enz.) die hij kan gebruiken om zich op de site te identificeren.
  16. Een ander groot voordeel voor de gebruikersinterface dat in het kader van deze inspanning wordt nagestreefd, is de browser te helpen meer te weten te komen over de sessie van de gebruiker - in de eerste plaats als wie hij op dat moment is ingelogd - zodat hij dat in het chroom van de browser kan laten zien.
  17. Door de gedistribueerde aard van dit systeem, vermijdt het lock-in met grote sites zoals Facebook, Twitter, Google, enz. Elk individu kan zijn eigen domein bezitten en dus optreden als zijn eigen identiteitsprovider.

Dit is niet echt "formuliergebaseerde authenticatie voor websites". Maar het is een poging om van de huidige norm van formuliergebaseerde authenticatie over te stappen op iets veiligers: browser-ondersteunde authenticatie.

Commentaren (2)