Vraag De definitieve gids voor op formulieren gebaseerde authenticatie van websites [gesloten]


Op formulieren gebaseerde authenticatie voor websites

Wij zijn van mening dat Stack Overflow niet alleen een hulpmiddel moet zijn voor zeer specifieke technische vragen, maar ook voor algemene richtlijnen voor het oplossen van variaties op veel voorkomende problemen. "Formgebaseerde authenticatie voor websites" zou een goed onderwerp moeten zijn voor een dergelijk experiment.

Het moet onderwerpen bevatten zoals:

  • Hoe inloggen?
  • Hoe uit te loggen
  • Hoe ingelogd te blijven
  • Beheer van cookies (inclusief aanbevolen instellingen)
  • SSL / HTTPS-codering
  • Hoe wachtwoorden op te slaan
  • Geheime vragen gebruiken
  • Gebruikersnaam / wachtwoord-functionaliteit vergeten
  • Gebruik van nonces voorkomen cross-site request forgeries (CSRF)
  • OpenID
  • "Onthoud mij" checkbox
  • Browser-automatisch aanvullen van gebruikersnamen en wachtwoorden
  • Geheime URL's (openbaar URL beschermd door digest)
  • Controle van de wachtwoordsterkte
  • E-mail validatie
  • en nog veel meer over  op formulieren gebaseerde authenticatie...

Er mogen geen zaken als:

  • Rollen en autorisatie
  • HTTP-basisverificatie

Help ons alstublieft door:

  1. Subtopics voorstellen
  2. Goede artikelen over dit onderwerp indienen
  3. Het officiële antwoord bewerken

4992


oorsprong


antwoorden:


DEEL I: Hoe kan ik inloggen?

We gaan ervan uit dat u al weet hoe u een login- en wachtwoord-HTML-formulier moet maken dat de waarden naar een script op de server POST voor authenticatie. In de onderstaande secties worden patronen behandeld voor een goed praktisch auth en hoe de meest voorkomende beveiligingsproblemen worden voorkomen.

Naar HTTPS of niet naar HTTPS?

Tenzij de verbinding al veilig is (dat wil zeggen, getunneld via HTTPS met behulp van SSL / TLS), worden uw waarden voor het aanmeldingsformulier in cleartext verzonden, zodat iedereen die afluist op de lijn tussen de browser en de webserver logins kan lezen als ze passeren door. Dit type aftapping wordt routinematig uitgevoerd door overheden, maar in het algemeen zullen we geen 'eigen' draden behandelen anders dan dit te zeggen: gebruik HTTPS als u iets belangrijks beveiligt.

In wezen de enige praktisch manier om te beschermen tegen afluisteren / packet sniffing tijdens het inloggen door gebruik te maken van HTTPS of een ander op certificaten gebaseerd versleutelingsschema (bijvoorbeeld TLS) of een beproefd en getest uitdagingsantwoordschema (bijvoorbeeld de Diffie-Hellmanop basis van SRP). Elke andere methode kan eenvoudig worden omzeild door een afluister-aanvaller.

Als u bereid bent een beetje onpraktisch te worden, kunt u natuurlijk ook een of andere vorm van een twee-factorenauthenticatieschema gebruiken (bijvoorbeeld de Google Authenticator-app, een fysiek 'cold war style' codeboek of een RSA-sleutelgenerator-dongle). Als het correct wordt toegepast, zou dit zelfs met een onbeveiligde verbinding kunnen werken, maar het is moeilijk voorstelbaar dat een ontwikkelaar bereid is om twee-factor auth maar niet SSL te implementeren.

(Do not) Roll-your-own JavaScript-codering / hashen

Gezien de niet-nulkosten en de ervaren technische problemen bij het instellen van een SSL-certificaat op uw website, zijn sommige ontwikkelaars geneigd om hun eigen hash- of versleutelingshulpprogramma's in de browser te gebruiken om te voorkomen dat cleartext-logins via een onbeveiligde draad worden doorgegeven.

Hoewel dit een nobele gedachte is, is het in wezen nutteloos (en kan het een zijn) beveiligingsfout) tenzij het wordt gecombineerd met een van bovenstaande - dat wil zeggen: het beveiligen van de regel met sterke codering of met een beproefd en getest beproevingsmechanisme (als je niet weet wat dat is, weet dan dat het een is van de moeilijkst te bewijzen, moeilijkst te ontwerpen en moeilijkst te implementeren concepten in digitale beveiliging).

Hoewel het klopt dat hashing het wachtwoord kan zijn effectief tegen onthullen van wachtwoorden, het is kwetsbaar voor het herspelen van aanvallen, Man-in-The-Middle-aanvallen / kapingen (als een aanvaller enkele bytes in uw onbeveiligde HTML-pagina kan injecteren voordat deze uw browser bereikt, kunnen ze eenvoudig de hashing in JavaScript uitspreken), of brute-force aanvallen (aangezien je de aanvaller zowel gebruikersnaam, zout en gehasht wachtwoord overhandigt).

CAPTCHAS tegen de mensheid

CAPTCHA's zijn bedoeld om een ​​specifieke aanvalscategorie te dwarsbomen: geautomatiseerd woordenboek / brute force-trial-and-error zonder menselijke operator. Het lijdt geen twijfel dat dit een reële bedreiging is, maar er zijn manieren om dit probleemloos aan te pakken waarvoor geen CAPTCHA nodig is, met name goed ontworpen serverside-login-beperkingsschema's - we zullen die later bespreken.

Weet dat CAPTCHA-implementaties niet hetzelfde zijn; ze zijn vaak niet door mensen oplosbaar, de meeste zijn in feite niet effectief tegen bots, ze zijn allemaal niet effectief tegen goedkope arbeid in de derde wereld (volgens OWASP, het huidige percentage sweatshop is $ 12 per 500 tests), en sommige implementaties zijn in sommige landen technisch illegaal (zie OWASP Authenticatie Cheat Sheet). Als u een CAPTCHA moet gebruiken, gebruikt u Google's reCAPTCHA, omdat het per definitie OCR-hard is (omdat het al OCR-verkeerd geclassificeerde boekscans gebruikt) en heel moeilijk probeert om gebruiksvriendelijk te zijn.

Persoonlijk vind ik CAPTCHAS vaak vervelend en gebruik ik ze alleen als laatste redmiddel als een gebruiker een aantal keren niet heeft ingelogd en de vertragingen bij het vertragen maximaal zijn. Dit gebeurt zelden genoeg om acceptabel te zijn en het versterkt het systeem als geheel.

Wachtwoorden opslaan / inloggen verifiëren

Dit kan eindelijk algemeen bekend zijn na alle hooggepubliceerde hacks en lekken van gebruikersgegevens die we de afgelopen jaren hebben gezien, maar het moet gezegd worden: bewaar wachtwoorden niet in cleartext in uw database. Gebruikersdatabases worden routinematig gehackt, gelekt of opgespoord door middel van SQL-injectie. Als u Raw-wachtwoorden voor platte tekst opslaat, is dat een directe game-over voor uw inlogbeveiliging.

Dus als u het wachtwoord niet kunt opslaan, hoe controleert u dan of de login + wachtwoord combinatie POSTed van het inlogformulier correct is? Het antwoord is hashing met behulp van een sleutel afleidingsfunctie. Telkens wanneer een nieuwe gebruiker wordt gemaakt of een wachtwoord wordt gewijzigd, neemt u het wachtwoord en voert het door een KDF, zoals Argon2, bcrypt, scrypt of PBKDF2, en verandert het cleartext-wachtwoord ("correcthorsebatterystaple") in een lange, willekeurig uitziende reeks , wat een stuk veiliger is om op te slaan in uw database. Om een ​​aanmelding te verifiëren, voert u dezelfde hash-functie uit op het ingevoerde wachtwoord, waarbij u deze keer het zout doorgeeft en de resulterende hashreeks vergelijkt met de waarde die in uw database is opgeslagen. Argon2, bcrypt en scrypt slaan het zout met de hash al op. Kijk hier eens naar artikel op sec.stackexchange voor meer gedetailleerde informatie.

De reden dat een zout wordt gebruikt, is omdat hashing op zichzelf niet voldoende is - je zult een zogenaamd 'zout' willen toevoegen om de hasj tegen regenboogtafels. Een zout voorkomt effectief dat twee wachtwoorden die exact overeenkomen met worden opgeslagen als dezelfde hash-waarde, waardoor wordt voorkomen dat de hele database in één keer wordt gescand als een aanvaller een wachtwoordinsporingsaanval uitvoert.

Een cryptografische hash moet niet worden gebruikt voor wachtwoordopslag, omdat door de gebruiker geselecteerde wachtwoorden niet sterk genoeg zijn (dat wil zeggen, bevatten gewoonlijk niet genoeg entropie) en een aanval met wachtwoord raden in relatief korte tijd kan worden voltooid door een aanvaller met toegang tot de hashes. Dit is de reden waarom een ​​KDF wordt gebruikt - deze effectief "de sleutel uitstrekken" wat betekent dat elke wachtwoordgissing die een aanvaller maakt, meerdere keren herhalen van het hash-algoritme is, bijvoorbeeld 10.000 keer, waardoor het wachtwoord van de aanvaller 10.000 keer langzamer wordt.

Sessiegegevens - "U bent ingelogd als Spiderman69"

Nadat de server de aanmeldingsnaam en het wachtwoord voor uw gebruikersdatabase heeft geverifieerd en een overeenkomst heeft gevonden, heeft het systeem een ​​manier nodig om te onthouden dat de browser is geverifieerd. Dit feit zou alleen ooit serverzijde moeten zijn in de sessiegegevens.

Als u niet bekend bent met sessiegegevens, doet u het als volgt: een enkele willekeurig gegenereerde reeks wordt opgeslagen in een cookie waarvan de geldigheid afloopt en wordt gebruikt om te verwijzen naar een verzameling gegevens - de sessiegegevens - die op de server zijn opgeslagen. Als u een MVC-raamwerk gebruikt, wordt dit ongetwijfeld al afgehandeld.

Zorg er indien mogelijk voor dat de sessiecookie de veilige en HTTP Only-vlaggen heeft ingesteld bij verzending naar de browser. De httponly-vlag biedt enige bescherming tegen het lezen van de cookie door een XSS-aanval. De veilige vlag zorgt ervoor dat de cookie alleen via HTTPS wordt teruggestuurd en beschermt daarom tegen netwerksnuffelaanvallen. De waarde van de cookie moet niet voorspelbaar zijn. Wanneer een cookie met verwijzingen naar een niet-bestaande sessie wordt gepresenteerd, moet de waarde ervan onmiddellijk worden vervangen om te voorkomen sessie fixatie.

DEEL II: Hoe te blijven aangemeld - Het beruchte "Onthoud mij" aankruisvak

Persistent Login Cookies ("remember me" -functionaliteit) vormen een gevarenzone; aan de ene kant zijn ze volledig net zo veilig als conventionele logins wanneer gebruikers begrijpen hoe ze moeten worden gebruikt; en aan de andere kant zijn ze een enorm veiligheidsrisico voor onzorgvuldige gebruikers, die ze kunnen gebruiken op openbare computers en vergeten uit te loggen, en die misschien niet weten wat browsercookies zijn of hoe ze te verwijderen.

Persoonlijk houd ik van aanhoudende logins voor de websites die ik regelmatig bezoek, maar ik weet hoe ik ze veilig moet gebruiken. Als u zeker weet dat uw gebruikers hetzelfde weten, kunt u permanente aanmeldingen met een schoon geweten gebruiken. Als dat niet het geval is, wel, dan kunt u zich misschien abonneren op de filosofie dat gebruikers die achteloos zijn met hun inloggegevens, het op zichzelf hebben genomen als ze worden gehackt. Het is niet zo dat we naar de huizen van onze gebruikers gaan en al die face-to-face-inducerende Post-It-notities afscheuren met wachtwoorden die ze ook aan de rand van hun beeldscherm hebben opgesteld.

Natuurlijk kunnen sommige systemen het zich niet veroorloven ieder accounts gehackt; voor dergelijke systemen is het op geen enkele manier gerechtvaardigd dat u permanente logins heeft.

Als je beslist om blijvende login-cookies te implementeren, doe je het als volgt:

  1. Neem eerst even de tijd om te lezen Paragon Initiative's artikel over het onderwerp. Je zult een aantal elementen goed moeten hebben, en het artikel kan elk goed uitleggen.

  2. En gewoon om een ​​van de meest voorkomende valkuilen te herhalen, Sla NIET HET AANHOUDENDE AANMELDINGSCOKJE (TOKEN) IN UW DATABASE OP, ALLEEN EEN HITTE VAN HET! Het inlogtoken is wachtwoordequivalent, dus als een aanvaller uw database heeft gevonden, kunnen ze de tokens gebruiken om zich aan te melden bij een account, net als bij cleartext-inlog-wachtwoordcombinaties. Gebruik daarom hashing (volgens https://security.stackexchange.com/a/63438/5002 een zwakke hash doet het prima voor dit doel) bij het opslaan van persistente inlogtokens.

DEEL III: Geheime vragen gebruiken

Implementeer geen 'geheime vragen'. De 'geheime vragen'-functie is een anti-patroon voor beveiliging. Lees de paper van link nummer 4 van de MUST-READ lijst. Je kunt Sarah Palin daarnaar vragen, na haar Yahoo! e-mailaccount werd gehackt tijdens een vorige presidentiële campagne omdat het antwoord op haar beveiligingsvraag 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 kan opheffen van zijn blog, LinkedIn-profiel of iets dergelijks

  • Elke vraag die gemakkelijker te beantwoorden is dan het raden van hun wachtwoord. Wat, voor elk fatsoenlijk wachtwoord, elke vraag is die je je kunt voorstellen

Concluderend, beveiligingsvragen zijn inherent onveilig in vrijwel al hun vormen en variaties en zouden om welke reden dan ook niet in een authenticatieschema moeten worden gebruikt.

De echte reden waarom beveiligingsvragen zelfs in het wild bestaan, is dat ze gemakkelijk de kosten kunnen besparen van een paar support calls van gebruikers die geen toegang hebben tot hun e-mail om een ​​reactiveringscode te krijgen. Dit ten koste van de veiligheid en de reputatie van Sarah Palin. De moeite waard? Waarschijnlijk niet.

DEEL IV: Vergeten wachtwoordfunctionaliteit

Ik heb al genoemd waarom je zou moeten gebruik nooit beveiligingsvragenvoor het afhandelen van vergeten / verloren gebruikerswachtwoorden; het spreekt vanzelf dat u gebruikers nooit hun werkelijke wachtwoorden mag e-mailen. Er zijn nog minstens twee meer al te gebruikelijke valkuilen om te vermijden op dit gebied:

  1. doe niet reset een vergeten wachtwoord voor een automatisch geactiveerd sterk wachtwoord - dergelijke wachtwoorden zijn notoir moeilijk te onthouden, wat betekent dat de gebruiker deze moet wijzigen of opschrijven - bijvoorbeeld op een felle gele post-it op de rand van hun monitor. In plaats van een nieuw wachtwoord in te stellen, kunt u gebruikers meteen een nieuw wachtwoord laten kiezen - wat ze sowieso willen doen. (Een uitzondering hierop kan zijn als de gebruikers universeel een wachtwoordbeheerder gebruiken om wachtwoorden op te slaan / beheren die normaal gesproken niet meer te onthouden zijn zonder deze op te schrijven).

  2. Altijd de verloren wachtwoordcode / token in de database hashen. NOG EEN KEER, deze code is een ander voorbeeld van een wachtwoordequivalent, dus het MOET worden gehashed in het geval dat een aanvaller jouw database in handen krijgt. Wanneer om een ​​verloren wachtwoordcode wordt gevraagd, stuur dan de leesbare code naar het e-mailadres van de gebruiker, sla het op, sla de hash op in je database - en gooi het origineel weg. Net als een wachtwoord of een permanent inlogtoken.

Een laatste opmerking: zorg er altijd voor dat uw interface voor het invoeren van de 'verloren wachtwoordcode' minstens zo veilig is als uw aanmeldingsformulier zelf, of dat een aanvaller dit eenvoudigweg gebruikt om toegang te krijgen. Het is een goed begin om zeer lange 'verloren wachtwoordcodes' (bijvoorbeeld 16 hoofdlettergevoelige alfanumerieke tekens) te genereren, maar overweeg hetzelfde throttling-schema toe te voegen dat u voor het aanmeldingsformulier zelf doet.

DEEL V: Wachtwoordsterkte controleren

Eerst wil je dit kleine artikel lezen voor een realiteitscheck: De 500 meest voorkomende wachtwoorden

Oké, dus misschien is de lijst niet de kanoniek lijst van meest voorkomende wachtwoorden op ieder systeem overal ooit, maar het is een goede indicatie van hoe slecht mensen hun wachtwoord kiezen als er geen gehandhaafd beleid is. Bovendien ziet de lijst er angstaanjagend dicht bij huis uit wanneer u deze vergelijkt met openbaar beschikbare analyses van recentelijk gestolen wachtwoorden.

Dus: zonder minimum vereisten voor wachtwoordsterkte, gebruikt 2% van de gebruikers een van de 20 meest gebruikte wachtwoorden. Betekenis: als een aanvaller slechts 20 pogingen onderneemt, is 1 op de 50 accounts op uw website kwetsbaar.

Dit moet worden verhinderd door de entropie van een wachtwoord te berekenen en vervolgens een drempel toe te passen. Het nationaal instituut voor normen en technologie (NIST) Speciale publicatie 800-63 heeft een aantal zeer goede suggesties. Dat, in combinatie met een woordenboek en toetsenbordindeling analyse (bijvoorbeeld 'qwertyuiop' is een slecht wachtwoord), kan 99% van alle slecht geselecteerde wachtwoorden afwijzen op een niveau van 18 stukjes entropie. Gewoon het berekenen van de wachtwoordsterkte en een visuele sterktemeter weergeven voor een gebruiker is goed, maar onvoldoende. Tenzij het wordt afgedwongen, zullen veel gebruikers dit waarschijnlijk negeren.

En voor een verfrissende kijk op de gebruiksvriendelijkheid van hoge entropische wachtwoorden, die van Randall Munroe Wachtwoord sterkte xkcd wordt sterk aanbevolen.

DEEL VI: Veel meer - Of: Voorspellende pogingen tot snelvuur voorkomen

Bekijk eerst de cijfers: Password Recovery-snelheden - Hoe lang zal uw wachtwoord opstaan

Als u niet de tijd heeft om door de tabellen in die link te bladeren, vindt u hier de lijst:

  1. Het duurt vrijwel geen tijd om een ​​zwak wachtwoord te kraken, zelfs als je het met een abacus kraakt

  2. Het duurt vrijwel geen tijd om een ​​alfanumeriek wachtwoord van 9 tekens te kraken, als dat zo is niet hoofdlettergevoelig

  3. Het duurt vrijwel geen tijd om een ​​ingewikkeld wachtwoord, symbolen-en-letters-en-cijfers, hoofdletters en kleine letters te kraken, als dat zo is minder dan 8 tekens lang (een desktop pc kan in een kwestie van dagen of zelfs uren de hele sleutelruimte doorzoeken tot 7 tekens)

  4. Het zou echter een buitensporige hoeveelheid tijd kosten om zelfs een wachtwoord van zes tekens te kraken, als je beperkt was tot één poging per seconde!

Dus wat kunnen we leren van deze cijfers? Nou, veel, maar we kunnen ons concentreren op het belangrijkste deel: het feit dat het voorkomen van grote aantallen opeenvolgende inlogpogingen na elkaar (dat wil zeggen de brute kracht aanval) is echt niet zo moeilijk. Maar het voorkomen rechts is niet zo eenvoudig als het lijkt.

Over het algemeen heb je drie keuzes die allemaal effectief zijn tegen brute-force aanvallen (en woordenboekaanvallen, maar aangezien u al een sterk wachtwoordbeleid hanteert, zouden ze geen probleem moeten zijn):

  • Aanwezig a CAPTCHA na N mislukte pogingen (vervelend als de hel en vaak niet effectief - maar ik herhaal mezelf hier)

  • Accounts vergrendelen en e-mailverificatie vereisen na N mislukte pogingen (dit is een DoS aanval wacht om te gebeuren)

  • En tenslotte, login throttling: dat wil zeggen, het instellen van een tijdsvertraging tussen pogingen na N mislukte pogingen (ja, DoS-aanvallen zijn nog steeds mogelijk, maar ze zijn in ieder geval veel minder waarschijnlijk en veel gecompliceerder om uit te voeren).

Beste praktijk # 1: Een korte vertraging die toeneemt met het aantal mislukte pogingen, zoals:

  • 1 mislukte poging = geen vertraging
  • 2 mislukte pogingen = 2 sec vertraging
  • 3 mislukte pogingen = 4 sec vertraging
  • 4 mislukte pogingen = 8 sec vertraging
  • 5 mislukte pogingen = 16 sec vertraging
  • enz.

DoS die dit schema aanvalt, zou zeer onpraktisch zijn, omdat de resulterende blokkeringstijd iets groter is dan de som van de vorige uitsluitingstijden.

Ter verduidelijking: de vertraging is niet een vertraging voordat het antwoord op de browser wordt geretourneerd. Het is meer een time-out of een ongevoelige periode waarin inlogpogingen naar een specifieke account of van een specifiek IP-adres in het geheel niet worden geaccepteerd of geëvalueerd. Dat wil zeggen, correcte inloggegevens zullen niet terugkeren bij een succesvolle aanmelding, en onjuiste inloggegevens zullen geen vertragingstoename veroorzaken.

Beste praktijk # 2: Een gemiddelde vertraging die in werking treedt na N mislukte pogingen, zoals:

  • 1-4 mislukte pogingen = geen vertraging
  • 5 mislukte pogingen = 15-30 min. Vertraging

DoS die dit schema aanvalt, is vrij onpraktisch, 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 u niet leuk vinden.

Beste praktijk # 3: Combinatie van de twee benaderingen - ofwel een vaste, korte tijdsvertraging die van kracht wordt na N mislukte pogingen, zoals:

  • 1-4 mislukte pogingen = geen vertraging
  • 5+ mislukte pogingen = 20 sec vertraging

Of, een toenemende vertraging met een vaste bovengrens, zoals:

  • 1 mislukte poging = 5 sec vertraging
  • 2 mislukte pogingen = 15 sec vertraging
  • 3+ mislukte pogingen = 45 sec vertraging

Dit definitieve schema is overgenomen uit de OWASP-tips voor beste praktijken (link 1 van de lijst met MUST READ) en moet als beste praktijk worden beschouwd, ook al is dit weliswaar aan de beperkende kant.

Als vuistregel echter zou ik willen zeggen: hoe sterker uw wachtwoordbeleid is, hoe minder u gebruikers met vertragingen moet bugmen. Als u sterke (hoofdlettergevoelige alfanumerieke tekens + vereiste cijfers en symbolen) van meer dan 9 tekens nodig hebt, kunt u de gebruikers 2-4 niet-vertraagde wachtwoordpogingen geven voordat de beperking wordt geactiveerd.

DoS die dit laatste inlogregelingsschema zou aanvallen heel onpraktisch. En als laatste kunt u altijd blijvende (cookie) logins (en / of een door CAPTCHA geverifieerd inlogformulier) laten passeren, zodat legitieme gebruikers niet eens worden vertraagd terwijl de aanval aan de gang is. Op die manier wordt de zeer onpraktische DoS-aanval een uiterst onpraktische aanval.

Daarnaast is het logisch om agressievere beperkingen op beheerdersaccounts aan te brengen, omdat dit de aantrekkelijkste toegangspunten zijn

DEEL VII: Gedistribueerde Brute Force-aanvallen

Even terzijde, geavanceerdere aanvallers proberen login-throttling te omzeilen door 'hun activiteiten te verspreiden':

  • Verspreiden van de pogingen op een botnet om het markeren van IP-adressen te voorkomen

  • In plaats van één gebruiker te kiezen en de 50.000 meest voorkomende wachtwoorden te proberen (wat ze niet kunnen doen vanwege onze beperking), kiezen ze HET meest voorkomende wachtwoord en proberen het in plaats daarvan tegen 50.000 gebruikers. Op die manier komen ze niet alleen in de buurt van pogingen tot maximale pogingen, zoals CAPTCHA's en inlogbeperkingen, hun kans op succes neemt ook toe, aangezien het meest voorkomende wachtwoord nummer 1 veel waarschijnlijker is dan nummer 49.995

  • Verspreid de inlogverzoeken voor elk gebruikersaccount, bijvoorbeeld 30 seconden uit elkaar, om onder de radar te sluipen

Hier zou de beste praktijk zijn het aantal mislukte aanmeldingen registreren, systeembreeden een gemiddelde van de slechte inlogfrequentie van uw site gebruiken als basis voor een bovengrens die u vervolgens oplegt aan alle gebruikers.

Te abstract? Laat me herformuleren:

Stel dat uw site de afgelopen drie maanden gemiddeld 120 onjuiste aanmeldingen per dag heeft gehad. Gebruikend dat (het lopende gemiddelde), zou uw systeem de globale grens tot 3 keer dat kunnen stellen - dwz. 360 mislukte pogingen gedurende een periode van 24 uur. Als het totale aantal mislukte pogingen voor alle accounts dat aantal binnen een dag overschrijdt (of beter nog, controleer dan de snelheid van de versnelling en activeer op een berekende drempelwaarde), activeert het systeem de login-throttling - dit betekent korte vertragingen voor ALLE gebruikers (nog steeds, met uitzondering van cookielogins en / of backup CAPTCHA-aanmeldingen).

Ik heb ook een vraag geplaatst bij meer details en een hele goede discussie over hoe je lastige pitfans kunt voorkomen in het afweren van gedistribueerde brute force-aanvallen

DEEL VIII: Providers voor authenticatie en authenticatie met twee factoren

Referenties kunnen worden aangetast, hetzij door exploits, wachtwoorden worden opgeschreven en verloren, laptops met sleutels worden gestolen, of gebruikers die inloggen bij phishing-sites. Aanmeldingen kunnen verder worden beveiligd met tweefactorauthenticatie, waarbij gebruik wordt gemaakt van out-of-band factoren zoals codes voor eenmalig gebruik die worden ontvangen van een telefoongesprek, een sms-bericht, een app of een dongle. Verschillende providers bieden tweefactorauthenticatiediensten.

Authenticatie kan volledig worden gedelegeerd naar een single sign-on-service, waar een andere provider de inloggegevens verwerkt. Dit duwt het probleem naar een vertrouwde derde partij. Google en Twitter bieden beide op standaarden gebaseerde SSO-services, terwijl Facebook een vergelijkbare eigen oplossing biedt.

LEES-LEES LINKS Over webverificatie

  1. OWASP gids voor authenticatie / OWASP Authenticatie Cheat Sheet
  2. Dos en Don'ts van clientverificatie op het web (zeer leesbaar MIT research paper)
  3. Wikipedia: HTTP-cookie
  4. Persoonlijke kennisvragen voor fallback-authenticatie: beveiligingsvragen in het tijdperk van Facebook (zeer leesbaar Berkeley-onderzoekspapier)

3497



Definitief artikel

Inloggegevens verzenden

De enige praktische manier om inloggegevens 100% veilig te verzenden, is door te gebruiken SSL. Het gebruik van JavaScript in hash is niet veilig. Veelvoorkomende valkuilen voor het hashen van wachtwoorden aan de clientzijde:

  • Als de verbinding tussen de client en de server niet is versleuteld, is alles wat u doet kwetsbaar voor man-in-the-middle-aanvallen. Een aanvaller kan het inkomende javascript vervangen om de hashing te verbreken of alle inloggegevens naar hun server te sturen, ze kunnen naar reacties van klanten luisteren en de gebruikers perfect nabootsen, enz. SSL met vertrouwde certificaatautoriteiten is ontworpen om mitig-aanvallen te voorkomen.
  • Het gehashte wachtwoord dat door de server wordt ontvangen is minder veilig als u geen extra doet, overbodig werk op de server.

Er is nog een andere veilige methode genaamd SRP, maar het is gepatenteerd (hoewel het dat wel is vrij gelicenseerd) en er zijn weinig goede implementaties beschikbaar.

Wachtwoorden opslaan

Sla wachtwoorden nooit op als platte tekst in de database. Zelfs niet als je niet om de beveiliging van je eigen site geeft. Neem aan dat sommige van uw gebruikers het wachtwoord van hun online bankrekening opnieuw zullen gebruiken. Dus sla het gehashte wachtwoord op en gooi het origineel weg. En zorg ervoor dat het wachtwoord niet wordt weergegeven in toegangslogboeken of toepassingslogboeken. OWASP beveelt het gebruik van Argon2 aan als uw eerste keuze voor nieuwe toepassingen. Als dit niet beschikbaar is, moet PBKDF2 of scrypt worden gebruikt. En als uiteindelijk geen van bovenstaande beschikbaar is, gebruik dan bcrypt.

Hashes op zichzelf zijn ook onzeker. Identieke wachtwoorden betekenen bijvoorbeeld identieke hashes - dit maakt hash opzoektabellen een effectieve manier om veel wachtwoorden tegelijk te kraken. Sla in plaats daarvan de gezouten hash. Een zout is een tekenreeks die aan het wachtwoord is toegevoegd voorafgaand aan het hashen - gebruik een ander (willekeurig) zout per gebruiker. Het zout is een publieke waarde, dus u kunt ze opslaan met de hash in de database. Zien hier voor meer hierover.

Dit betekent dat u de gebruiker niet zijn vergeten wachtwoorden kunt sturen (omdat u alleen de hash hebt). Stel het gebruikerswachtwoord niet opnieuw in tenzij u de gebruiker hebt geverifieerd (gebruikers moeten kunnen aantonen dat ze e-mails kunnen lezen die naar het opgeslagen (en gevalideerde) e-mailadres zijn verzonden).

Veiligheidsvragen

Beveiligingsvragen zijn onveilig - vermijd ze te gebruiken. Waarom? Alles wat een beveiligingsvraag doet, een wachtwoord doet het beter. Lezen DEEL III: Geheime vragen gebruiken in @Jens Roland antwoord hier in deze wiki.

Sessie cookies

Nadat de gebruiker zich heeft aangemeld, stuurt de server de gebruiker een sessiecookie. De server kan de gebruikersnaam of id van de cookie ophalen, maar niemand anders kan zo'n cookie genereren (TODO-uitlegmechanismen).

Cookies kunnen worden gekaapt: ze zijn alleen zo veilig als de rest van de machine van de klant en andere communicatie. Ze kunnen worden gelezen vanaf schijf, gesnoven in netwerkverkeer, opgetild door een cross-site scriptingaanval, gefouilleerd van een vergiftigde DNS zodat de client zijn cookies naar de verkeerde servers stuurt. Stuur geen permanente cookies. Cookies moeten aan het einde van de clientsessie verlopen (browser sluit of verlaat uw domein).

Als u uw gebruikers automatisch wilt laten registreren, kunt u een permanente cookie instellen, maar deze moet verschillen van een cookie voor de volledige sessie. U kunt een extra vlag instellen waarvoor de gebruiker automatisch is ingelogd en moet voor echt inloggen voor gevoelige bewerkingen. Dit is populair bij winkelsites die u een naadloze, gepersonaliseerde winkelervaring willen bieden, maar toch uw financiële gegevens beschermen. Wanneer u bijvoorbeeld terugkeert naar Amazon, krijgt u een pagina te zien die eruit ziet alsof u bent ingelogd, maar wanneer u een bestelling plaatst (of uw verzendadres, creditcard, enz. Wijzigt), vragen zij u dit te bevestigen je wachtwoord.

Financiële websites zoals banken en creditcards hebben daarentegen alleen gevoelige gegevens en mogen geen automatische login of een low-security-modus toestaan.

Lijst met externe bronnen


387



Ten eerste een sterke waarschuwing dat dit antwoord niet de beste pasvorm is voor deze exacte vraag. Het moet zeker niet het beste antwoord zijn!

Ik ga door en noem Mozilla's voorstel BrowserID (of misschien meer precies, de Geverifieerd e-mail protocol) in de geest van het vinden van een upgradepad naar betere benaderingen voor authenticatie in de toekomst.

Ik zal het op deze manier samenvatten:

  1. Mozilla is een non-profitorganisatie met waarden die goed aansluiten bij het vinden van goede oplossingen voor dit probleem.
  2. De realiteit van vandaag is dat de meeste websites op formulieren gebaseerde authenticatie gebruiken
  3. Op formulieren gebaseerde authenticatie heeft een groot nadeel, wat een verhoogd risico op phishing. Gebruikers wordt gevraagd om gevoelige informatie in te voeren in een gebied dat wordt beheerd door een externe entiteit in plaats van een gebied dat wordt beheerd door hun gebruikersagent (browser).
  4. Omdat browsers impliciet vertrouwd zijn (het hele idee van een User Agent is om namens de Gebruiker op te treden), kunnen ze helpen deze situatie te verbeteren.
  5. De primaire kracht die de voortgang tegenhoudt is hier inzet impasse. Oplossingen moeten worden opgesplitst in stappen die zelf een extra voordeel bieden.
  6. De eenvoudigste gedecentraliseerde methode voor het uiten van identiteit die is ingebouwd in de internetinfrastructuur, is de domeinnaam.
  7. Als een tweede niveau voor het uiten van identiteit, beheert elk domein zijn eigen set accounts.
  8. Het formulier-account@domein "is beknopt en wordt ondersteund door een breed scala aan protocollen en URI-schema's. Een dergelijke identifier wordt natuurlijk het meest universeel erkend als een e-mailadres.
  9. E-mailproviders zijn nu al de de facto primaire identiteitsproviders online. Met de huidige instellingen voor het opnieuw instellen van het wachtwoord kunt u meestal de controle over een account overnemen als u kunt aantonen dat u het bijbehorende e-mailadres van die account beheert.
  10. Het geverifieerde e-mailprotocol is voorgesteld om een ​​veilige methode te bieden, gebaseerd op cryptografie met openbare sleutels, voor het stroomlijnen van het proces om te bewijzen aan domein B dat u een account hebt op domein A.
  11. Voor browsers die het Geverifieerde e-mailprotocol (op dit moment allemaal) niet ondersteunen, biedt Mozilla een vulstuk dat het protocol implementeert in client-side JavaScript-code.
  12. Voor e-maildiensten die het Geverifieerde e-mailprotocol niet ondersteunen, staat het protocol derden toe om op te treden als een vertrouwde tussenpersoon, waarbij wordt beweerd dat zij het eigendom van een gebruiker van een account hebben geverifieerd. Het is niet wenselijk om een ​​groot aantal van dergelijke derden te hebben; deze mogelijkheid is alleen bedoeld om een ​​upgradepad toe te staan, en het verdient veel de voorkeur dat e-mailservices deze beweringen zelf leveren.
  13. Mozilla biedt een eigen service om als een vertrouwde derde partij te handelen. Serviceproviders (dat wil zeggen, vertrouwende partijen) die het Geverifieerde e-mailprotocol implementeren, kunnen ervoor kiezen om de beweringen van Mozilla te vertrouwen of niet. De Mozilla-service verifieert het accounteigendom van gebruikers met behulp van de conventionele middelen voor het verzenden van een e-mail met een bevestigingslink.
  14. Serviceproviders kunnen dit protocol natuurlijk als een optie aanbieden naast elke andere authenticatiemethode die zij eventueel wensen aan te bieden.
  15. Een groot voordeel voor de gebruikersinterface is dat hier wordt gezocht naar de "identiteitselector". Wanneer een gebruiker een site bezoekt en ervoor kiest om zich te authenticeren, toont hun browser hen een selectie van e-mailadressen ("persoonlijk", "werk", "politiek activisme", enz.) Die zij kunnen gebruiken om zichzelf te identificeren op de site.
  16. Een ander groot gebruikersinterface voordeel wordt gezocht als onderdeel van deze inspanning de browser helpen meer te weten over de sessie van de gebruiker - met wie ze zijn aangemeld als momenteel, in de eerste plaats, zodat het kan worden weergegeven in de browser chrome.
  17. Vanwege het gedistribueerde karakter van dit systeem, vermijdt het lock-in voor grote sites zoals Facebook, Twitter, Google, etc. Elk individu kan zijn eigen domein bezitten en daarom optreden als zijn eigen identiteitsprovider.

Dit is niet strikt "op formulieren gebaseerde authenticatie voor websites". Maar het is een poging om van de huidige norm van op formulieren gebaseerde authenticatie over te schakelen naar iets veiliger: browser-ondersteunde authenticatie.


146



Ik dacht dat ik deze oplossing zou delen waarvan ik vond dat die prima werkte.

Ik noem het het Dummy Field (hoewel ik dit niet heb uitgevonden, crediteer mij dus niet).

Kortom: je hoeft dit alleen maar in je in te voegen <form> en controleer of het leeg is bij het valideren:

<input type="text" name="email" style="display:none" />

De kunst is om een ​​bot voor de gek te houden door te denken dat hij gegevens moet invoegen in een verplicht veld, daarom noemde ik de invoer "e-mail". Als je al een veld hebt met de naam e-mail die je gebruikt, probeer dan het dummy-veld een naam te geven zoals "bedrijf", "telefoon" of "e-mailadres". Kies gewoon iets waarvan je weet dat je het niet nodig hebt en wat klinkt als iets dat mensen normaal gesproken logisch vinden om in een webformulier in te vullen. Verberg nu de input veld met behulp van CSS of JavaScript / jQuery - wat je het beste past - alleen niet doen stel de invoer in type naar hidden of anders zal de bot er niet voor vallen.

Wanneer u het formulier valideert (client- of serverzijde), controleert u of uw dummy-veld is ingevuld om te bepalen of het door een mens of een bot is verzonden.

Voorbeeld:

In het geval van een mens: De gebruiker ziet het dummy-veld (in mijn geval met de naam 'e-mail') niet en probeert het niet te vullen. De waarde van het dummy-veld moet dus nog steeds leeg zijn wanneer het formulier is verzonden.

In het geval van een bot: De bot ziet een veld waarvan het type is text en een naam email (of hoe je het ook noemt) en zal logisch proberen het te vullen met de juiste gegevens. Het maakt niet uit of je het invoerformulier hebt gestileerd met een of andere mooie CSS, web-ontwikkelaars doen het altijd. Wat de waarde op het gebied van de dummy ook is, het maakt ons niet uit, als het maar groter is dan 0 karakters.

Ik heb deze methode gebruikt in een gastenboek in combinatie met CAPTCHAen sindsdien heb ik geen enkele spampost meer gezien. Ik had eerder een CAPTCHA-enige oplossing gebruikt, maar uiteindelijk resulteerde dit elk uur in ongeveer vijf spamberichten. Het toevoegen van het dummy-veld in het formulier is gestopt (althans tot nu toe) alle spam verschijnt.

Ik geloof dat dit ook prima kan worden gebruikt met een login- / authenticatieformulier.

Waarschuwing: Natuurlijk is deze methode niet 100% betrouwbaar. Bots kunnen worden geprogrammeerd om invoervelden met de stijl te negeren display:none erop toegepast. Je moet ook denken aan mensen die een vorm van automatische aanvulling gebruiken (zoals de meeste browsers hebben ingebouwd!) Om alle formuliervelden voor hen automatisch in te vullen. Ze kunnen net zo goed een dummieveld oppakken.

Je kunt dit ook een beetje variëren door het dummieveld zichtbaar te laten maar buiten de grenzen van het scherm, maar dit is helemaal aan jou.

Wees creatief!


120



Ik denk niet dat het bovenstaande antwoord "fout" is, maar er zijn grote gebieden van authenticatie die niet worden aangeraakt (of liever de nadruk ligt op "hoe cookesessies te implementeren", niet op "welke opties zijn beschikbaar en wat zijn de handelsmogelijkheden) offs".

Mijn voorgestelde bewerkingen / antwoorden zijn

  • Het probleem ligt meer bij het instellen van de account dan bij het controleren van het wachtwoord.
  • Het gebruik van twee-factorenautheniticatie is veel veiliger dan slimmere middelen voor wachtwoordversleuteling
  • Probeer NIET om uw eigen login-formulier of database-opslag van wachtwoorden te implementeren, tenzij de gegevens die worden opgeslagen zijn waardeloos bij het maken van een account en zelf gegenereerd (dat wil zeggen, web 2.0-stijl zoals Facebook, Flickr, enz.)

    1. Digest Authentication is een op standaarden gebaseerde aanpak die wordt ondersteund in alle grote browsers en servers, die zelfs over een beveiligd kanaal geen wachtwoord verzenden.

Dit voorkomt de noodzaak om "sessies" of cookies te hebben, omdat de browser zelf de communicatie telkens opnieuw zal versleutelen. Het is de meest "lichtgewicht" ontwikkelingsbenadering.

Ik raad dit echter niet aan, behalve voor openbare diensten met een lage waarde. Dit is een probleem met enkele van de andere antwoorden hierboven - probeer niet om serverauthenticatiemechanismen opnieuw te implementeren - dit probleem is opgelost en wordt ondersteund door de meeste grote browsers. Gebruik geen cookies. Bewaar niets in uw eigen met de hand gerolde database. Vraag gewoon, per verzoek, of het verzoek is voorzien van een handtekening. Al het andere moet worden ondersteund door configuratie en vertrouwde software van derden.

Dus ...

Ten eerste verwarren we de initiële creatie van een account (met een wachtwoord) met de opnieuw controleren van het wachtwoord. Als ik Flickr ben en mijn site voor de eerste keer maak, heeft de nieuwe gebruiker toegang tot nulwaarden (lege webruimte). Het maakt me echt niet uit of de persoon die het account aanmaakt, liegt over hun naam. Als ik een account maak van het ziekenhuisintranet / extranet, ligt de waarde in alle medische dossiers, en dus ook in do zorgen voor de identiteit (*) van de maker van het account.

Dit is het heel erg moeilijke deel. De enkel en alleen fatsoenlijke oplossing is een web van vertrouwen. U komt bijvoorbeeld als arts bij het ziekenhuis. U maakt een webpagina die ergens met uw foto wordt gehost, uw paspoortnummer en een openbare sleutel, en hasht ze allemaal met de privésleutel. Je bezoekt dan het ziekenhuis en de systeembeheerder kijkt naar je paspoort, kijkt of de foto bij je past en hashes de webpagina / foto-hash met de privé-sleutel van het ziekenhuis. Vanaf nu kunnen we sleutels en tokens veilig uitwisselen. Zoals iedereen die het ziekenhuis vertrouwt (er is de geheime saus trouwens). De systeembeheerder kan u ook een RSA dongle of andere two-factor authenticatie.

Maar dit is een lot van gedoe, en niet erg web 2.0. Het is echter de enige veilige manier om nieuwe accounts te maken die toegang hebben tot waardevolle informatie die niet zelf is gemaakt.

  1. Kerberos en SPNEGO - mechanismen voor eenmalige aanmelding bij een vertrouwde derde partij - in principe verifieert de gebruiker tegen een vertrouwde derde partij. (NB dit is op geen enkele manier het niet te vertrouwen OAuth)

  2. SRP - soort slimme wachtwoordverificatie zonder een vertrouwde derde partij. Maar hier komen we op het gebied van "het is veiliger om tweefactorauthenticatie te gebruiken, zelfs als dat duurder is"

  3. SSL client-kant - geef de clients een public key-certificaat (ondersteuning in alle belangrijke browsers - maar roept vragen op over de beveiliging van client-machines).

Uiteindelijk is het een afweging - wat kost een beveiligingsinbreuk ten opzichte van de kosten van het implementeren van veiligere benaderingen. Op een dag kunnen we een goede zien PKI algemeen geaccepteerd en dus niet meer eigen gerolde authenticatieformulieren en databases. Op een dag...


71



Gebruik bij het hashen geen snelle hash-algoritmen zoals MD5 (er bestaan ​​veel hardware-implementaties). Gebruik zoiets als SHA-512. Voor wachtwoorden zijn langzamere hashes beter.

Hoe sneller je hashes kunt maken, hoe sneller elke brute force-checker kan werken. Langzamere hashes zullen daarom brute forcering vertragen. Een langzaam hash-algoritme maakt bruut forceren onpraktisch voor langere wachtwoorden (8 cijfers +)


48



Een goed artikel over realistische schatting van de wachtwoordsterkte is:

Dropbox Tech Blog »Blog Archive» zxcvbn: realistische inschatting van wachtwoordsterkte


46



Mijn favoriete regel met betrekking tot authenticatiesystemen: gebruik wachtzinnen, geen wachtwoorden. Makkelijk te onthouden, moeilijk te kraken. Meer informatie: Coding Horror: wachtwoorden versus passphrases


41



Ik wil graag een suggestie toevoegen die ik heb gebruikt, gebaseerd op verdediging in de diepte. U hoeft niet hetzelfde auth & auth-systeem te hebben voor beheerders als gewone gebruikers. U kunt een afzonderlijk aanmeldingsformulier op een afzonderlijke URL hebben die een afzonderlijke code uitvoert voor verzoeken die hoge rechten verlenen. Deze kan keuzes maken die een totale pijn zijn voor gewone gebruikers. Een daarvan die ik heb gebruikt, is om de inlog-URL voor admin-toegang daadwerkelijk te versleutelen en de nieuwe url aan de beheerder te e-mailen. Stopt elke brute force-aanval meteen omdat je nieuwe URL willekeurig moeilijk kan zijn (heel lang willekeurige reeks), maar het enige ongemak van je beheerder is het volgen van een link in zijn e-mail. De aanvaller weet niet meer waar hij naartoe moet POSTEN.


20



Ik weet niet of het het beste was om dit te beantwoorden als een antwoord of als een opmerking. Ik koos voor de eerste optie.

Met betrekking tot de poing DEEL IV: Vergeten wachtwoordfunctionaliteit in het eerste antwoord zou ik iets willen zeggen over timingaanvallen.

In de Onthoud uw wachtwoord formulieren kan een aanvaller mogelijk een volledige lijst met e-mails controleren en detecteren welke zijn geregistreerd bij het systeem (zie onderstaande link).

Met betrekking tot het Vergeten wachtwoord-formulier zou ik willen toevoegen dat het een goed idee is om gelijke tijden tussen succesvolle en niet-succesvolle zoekopdrachten met een bepaalde vertragingsfunctie te gebruiken.

https://crypto.stanford.edu/~dabo/papers/webtiming.pdf


12