Den definitive guide til formularbaseret autentificering af websteder

Formularbaseret godkendelse til websteder

Vi mener, at Stack Overflow ikke kun bør være en ressource for meget specifikke tekniske spørgsmål, men også for generelle retningslinjer for, hvordan man løser variationer af almindelige problemer. "Formularbaseret autentificering til websteder" bør være et godt emne for et sådant eksperiment.

Det bør omfatte emner som f.eks:

  • Hvordan man logger ind
  • Hvordan man logger ud
  • Hvordan man forbliver logget ind
  • Håndtering af cookies (herunder anbefalede indstillinger)
  • SSL/HTTPS-kryptering
  • Sådan opbevares adgangskoder
  • Brug af hemmelige spørgsmål
  • Funktioner til at glemme brugernavn/adgangskode
  • Brug af nonces til at forhindre cross-site request forgeries (CSRF)
  • OpenID
  • "Husk mig" afkrydsningsfelt
  • Auto-udfyldning af brugernavne og adgangskoder i browseren
  • Hemmelige URL'er (offentlig URL beskyttet af digest)
  • Kontrol af passwordets styrke
  • Validering af e-mail
  • og meget mere om formularbaseret autentificering...

Det bør ikke omfatte ting som:

  • Roller og autorisation
  • grundlæggende HTTP-godkendelse

Hjælp os venligst ved at:

  1. Foreslå underemner
  2. Indsende gode artikler om dette emne
  3. Redigering af det officielle svar
Løsning

DEL I: Sådan logger du ind

Vi antager, at du allerede ved, hvordan man opbygger en HTML-formular til login+password, som sender værdierne til et script på serversiden til godkendelse. Afsnittene nedenfor vil omhandle mønstre for god praktisk auth, og hvordan man undgår de mest almindelige sikkerhedsfælder. To HTTPS or not to HTTPS? Medmindre forbindelsen allerede er sikker (dvs. tunneleret gennem HTTPS ved hjælp af SSL/TLS), vil værdierne i din login-formular blive sendt i klartekst, hvilket gør det muligt for enhver, der aflytter linjen mellem browser og webserver, at læse logins, mens de passerer igennem. Denne form for aflytning foretages rutinemæssigt af regeringer, men generelt vil vi ikke tage fat på 'ejede' ledninger andet end at sige dette: Bare brug HTTPS. Den eneste praktiske måde at beskytte sig mod aflytning/pakkesnifning under login er i bund og grund ved at bruge HTTPS eller en anden certifikatbaseret krypteringsordning (f.eks. [TLS][1]) eller en gennemprøvet & testet challenge-response-ordning (f.eks. den [Diffie-Hellman][2]-baserede SRP). Alle andre metoder kan let omgås af en aflytningsangriber. Hvis du er villig til at være lidt upraktisk, kan du naturligvis også anvende en form for to-faktor-autentifikationsordning (f.eks. Google Authenticator-appen, en fysisk kodebog i koldkrigsstil eller en RSA-nøglegenerator-dongle). Hvis det anvendes korrekt, kan dette fungere selv med en usikker forbindelse, men det er svært at forestille sig, at en udvikler vil være villig til at implementere to-faktor auth, men ikke SSL. (ikke) Roll-your-own JavaScript-kryptering/hashing I betragtning af de opfattede (om end nu [undgåelige][27]) omkostninger og tekniske vanskeligheder ved at oprette et SSL-certifikat på dit websted, er nogle udviklere fristet til at rulle deres egne hashing- eller krypteringsordninger i browseren for at undgå at sende klartekstlogins over en usikker forbindelse. Selv om dette er en ædel tanke, er det i bund og grund ubrugeligt (og kan være en [sikkerhedsbrist][3]), medmindre det kombineres med et af ovenstående - dvs. enten at sikre linjen med stærk kryptering eller bruge en gennemprøvet challenge-response-mekanisme (hvis du ikke ved, hvad det er, skal du bare vide, at det er et af de mest vanskelige at bevise, mest vanskelige at designe og mest vanskelige at implementere koncepter inden for digital sikkerhed). Selv om det er sandt, at hashing af adgangskoden kan være effektivt mod adgangskodeafsløring, er det sårbart over for replay-angreb, Man-In-The-Middle-angreb / hijackings (hvis en angriber kan injicere et par bytes i din usikrede HTML-side, før den når din browser, kan de simpelthen kommentere hashing i JavaScript) eller brute-force-angreb (da du giver angriberen både brugernavn, salt og hashet adgangskode). CAPTCHAS mod menneskeheden [CAPTCHA][4] er beregnet til at afværge en bestemt kategori af angreb: automatiseret ordbog/brute force trial-and-error uden menneskelig operatør. Der er ingen tvivl om, at dette er en reel trussel, men der er måder at håndtere det problemfrit på, som ikke kræver en CAPTCHA, specielt korrekt designede server-side login throttling ordninger - vi vil diskutere dem senere. Du skal vide, at CAPTCHA-implementeringer ikke er ens; de er ofte ikke menneskeligt opløselige, de fleste af dem er faktisk ineffektive mod bots, alle er ineffektive mod billig arbejdskraft fra den tredje verden (ifølge [OWASP][5] er den nuværende sweatshop-rate 12 dollars pr. 500 tests), og nogle implementeringer kan være teknisk set ulovlige i nogle lande (se [OWASP Authentication Cheat Sheet][6]). Hvis du skal bruge en CAPTCHA, så brug Google's [reCAPTCHA][7], da den pr. definition er OCR-hård (da den bruger allerede OCR-misklassificerede bogscanninger) og forsøger meget hårdt at være brugervenlig. Personligt har jeg en tendens til at finde CAPTCHAS irriterende og bruger dem kun som en sidste udvej, når en bruger har undladt at logge ind et antal gange og throttling-forsinkelserne er maxet ud. Det sker sjældent nok til at være acceptabelt, og det styrker systemet som helhed. Lagring af adgangskoder/verificering af logins Dette er måske endelig almen viden efter alle de meget omtalte hacks og lækager af brugerdata, vi har set i de seneste år, men det skal siges: Gem ikke adgangskoder i klartekst i din database. Brugerdatabaser bliver rutinemæssigt hacket, lækket eller fundet gennem SQL-injektion, og hvis du gemmer rå kodeord i klartekst, er det straks slut med hensyn til din login-sikkerhed. Så hvis du ikke kan gemme adgangskoden, hvordan kontrollerer du så, at kombinationen af login+adgangskode, der er POSTet fra loginformularen, er korrekt? Svaret er hashing ved hjælp af en [key derivation function][24]. Hver gang en ny bruger oprettes eller et password ændres, tager du passwordet og kører det gennem en KDF, såsom Argon2, bcrypt, scrypt eller PBKDF2, og forvandler cleartext passwordet ("correcthorsebatterystaple") til en lang, tilfældigt udseende streng, som er meget mere sikker at gemme i din database. For at verificere et login kører du den samme hashfunktion på det indtastede password, denne gang ved at indsætte saltet og sammenligne den resulterende hashstreng med den værdi, der er gemt i din database. Argon2, bcrypt og scrypt gemmer allerede saltet sammen med hash-strengen. Se denne [artikel][23] på sec.stackexchange for mere detaljerede oplysninger. Grunden til at der bruges et salt er, at hashing i sig selv ikke er tilstrækkeligt -- du ønsker at tilføje et såkaldt 'salt' for at beskytte hashen mod [regnbuetabeller][8]. Et salt forhindrer effektivt, at to passwords, der passer nøjagtigt sammen, bliver gemt som den samme hash-værdi, hvilket forhindrer, at hele databasen bliver scannet på én gang, hvis en angriber udfører et password guessing attack. En kryptografisk hash bør ikke anvendes til lagring af adgangskoder, fordi brugervalgte adgangskoder ikke er stærke nok (dvs. normalt ikke indeholder tilstrækkelig entropi), og et angreb med adgangskoder kan gennemføres på relativt kort tid af en angriber, der har adgang til hash-koderne. Det er derfor, der anvendes KDF'er - disse er effektivt ["stretch the key"][25], hvilket betyder, at hvert password-gæt, som en angriber foretager, medfører flere gentagelser af hash-algoritmen, f.eks. 10.000 gange, hvilket får angriberen til at gætte passwordet 10.000 gange langsommere. Sessionsdata - "Du er logget ind som Spiderman69" Når serveren har verificeret login og password i forhold til din brugerdatabase og fundet et match, skal systemet kunne huske, at browseren er blevet autentificeret. Dette faktum bør kun gemmes på serversiden i sessionsdataene.

Hvis du ikke er bekendt med sessionsdata, kan du se her, hvordan det fungerer: En enkelt tilfældigt genereret streng gemmes i en cookie, der udløber, og bruges til at henvise til en samling data - sessionsdataene - som er gemt på serveren. Hvis du bruger en MVC-ramme, er dette utvivlsomt allerede håndteret. Hvis det overhovedet er muligt, skal du sørge for, at sessioncookien har markeringerne Secure og HTTP Only indstillet, når den sendes til browseren. HttpOnly-flaget giver en vis beskyttelse mod, at cookien kan læses ved XSS-angreb. Flaget secure sikrer, at cookien kun sendes tilbage via HTTPS, og beskytter derfor mod netværkssniffingangreb. Cookiens værdi bør ikke være forudsigelig. Hvis en cookie, der henviser til en ikke-eksisterende session, præsenteres, bør dens værdi straks erstattes for at forhindre session fixering.

DEL II: Sådan forbliver du logget ind - den berygtede "Husk mig" afkrydsningsboks

Persistent Login Cookies ("husk mig" funktionalitet) er en farezone; på den ene side er de fuldstændig lige så sikre som konventionelle logins, når brugerne forstår at håndtere dem; på den anden side udgør de en enorm sikkerhedsrisiko i hænderne på uforsigtige brugere, som måske bruger dem på offentlige computere og glemmer at logge ud, og som måske ikke ved, hvad browser cookies er, eller hvordan man sletter dem. Personligt kan jeg godt lide vedvarende logins til de websteder, jeg besøger regelmæssigt, men jeg ved, hvordan man håndterer dem sikkert. Hvis du er sikker på, at dine brugere ved det samme, kan du bruge vedvarende logins med god samvittighed. Hvis ikke - ja, så kan du tilslutte dig filosofien om, at brugere, der er uforsigtige med deres loginoplysninger, selv har bragt det over sig, hvis de bliver hacket. Det er heller ikke sådan, at vi tager hjem til vores brugere og river alle de ansigtsløftende Post-It-sedler med adgangskoder af, som de har liggende på kanten af deres skærme. Nogle systemer har naturligvis ikke råd til at få nogle konti hacket; for sådanne systemer er der ingen måde at retfærdiggøre vedvarende logins på. Hvis du beslutter dig for at implementere vedvarende login-cookies, så er det sådan her du gør det:

  1. Først skal du tage dig lidt tid til at læse Paragon Initiative's artikel om emnet. Du skal have en række elementer på plads, og artiklen forklarer hvert enkelt element godt.
  2. Og bare for at gentage en af de mest almindelige faldgruber: LAGER IKKE DEN PERSISTENTE LOGIN COOKIE (TOKEN) I DIN DATABASE, KUN EN HASH AF DEN! Login token er Password Equivalent, så hvis en angriber fik fat i din database, kunne de bruge tokens til at logge ind på enhver konto, ligesom hvis de var cleartext login-password kombinationer. Derfor skal du bruge hashing (ifølge https://security.stackexchange.com/a/63438/5002 er en svag hash helt fin til dette formål), når du lagrer vedvarende login-tokens.

    DEL III: Brug af hemmelige spørgsmål

    Don't implementere 'hemmelige spørgsmål'. Funktionen 'hemmelige spørgsmål' er et sikkerhedsmæssigt anti-mønster. Læs dokumentet fra link 4 på listen over MUST-READ-lister. Du kan spørge Sarah Palin om det, efter at hendes Yahoo! e-mail-konto blev hacket under en tidligere præsidentvalgkampagne, fordi svaret på hendes sikkerhedsspørgsmål var ... "Wasilla High School"! Selv med brugerspecificerede spørgsmål er det meget sandsynligt, at de fleste brugere vil vælge enten eller:

  • Et 'standard' hemmeligt spørgsmål som f.eks. moder's pigenavn eller yndlingsdyr
  • En simpel trivia, som enhver kan tage fra sin blog, LinkedIn-profil eller lignende
  • Et spørgsmål, der er lettere at besvare end at gætte deres adgangskode. Hvilket for ethvert ordentligt password er alle de spørgsmål, du kan forestille dig Sammenfattende er sikkerhedsspørgsmål i sig selv usikre i stort set alle deres former og variationer, og de bør ikke anvendes i en godkendelsesordning af nogen som helst grund. Den egentlige grund til, at sikkerhedsspørgsmål overhovedet findes i naturen, er, at de bekvemt sparer omkostningerne til et par supportopkald fra brugere, der ikke kan få adgang til deres e-mail for at få adgang til en reaktiveringskode. Dette på bekostning af sikkerheden og Sarah Palins omdømme. Er det det værd? Sandsynligvis ikke.

    DEL IV: Funktionalitet for glemt adgangskode

    Jeg har allerede nævnt, hvorfor du aldrig skal bruge sikkerhedsspørgsmål til håndtering af glemte/tabte brugeradgangskoder; det siger sig selv, at du heller aldrig bør sende brugerne deres faktiske adgangskoder pr. e-mail. Der er mindst to andre alt for almindelige faldgruber, der skal undgås på dette område:

  1. Lad være med at reset en glemt adgangskode til en autogenereret stærk adgangskode - sådanne adgangskoder er notorisk svære at huske, hvilket betyder, at brugeren enten skal ændre den eller skrive den ned - f.eks. på en knaldgul Post-It på kanten af skærmen. I stedet for at indstille en ny adgangskode kan du bare lade brugerne vælge en ny med det samme - hvilket de jo alligevel gerne vil gøre. (En undtagelse herfra kan være, hvis brugerne generelt bruger en password manager til at gemme/forvalte passwords, som normalt ville være umulige at huske uden at skrive det ned).
  2. Hash altid den tabte kode/token for det tabte password i databasen. AGAIN, denne kode er et andet eksempel på et Password Equivalent, så den SKAL hashes i tilfælde af at en angriber får fat i din database. Når der anmodes om en kode til et tabt kodeord, skal du sende koden i klartekst til brugerens e-mailadresse, derefter hashe den, gemme hashen i din database -- og kaste originalen væk. Ligesom et password eller et vedvarende login-token. En sidste bemærkning: Sørg altid for, at din grænseflade til indtastning af 'lost password code' er mindst lige så sikker som selve login-formularen, ellers vil en angriber simpelthen bruge denne til at få adgang i stedet. Det er en god start at sørge for at generere meget lange 'tabte adgangskodekoder' (f.eks. 16 alfanumeriske tegn, der tager hensyn til store og små bogstaver), men overvej at tilføje den samme begrænsningsordning som for selve loginformularen.

    DEL V: Kontrol af passwordstyrke

    Først bør du læse denne lille artikel for at få et realitetstjek: De 500 mest almindelige adgangskoder Okay, listen er måske ikke den kanoniske liste over de mest almindelige adgangskoder på nogle systemer nogle steder nogensinde*, men den er en god indikation af, hvor dårligt folk vælger deres adgangskoder, når der ikke er nogen håndhævet politik på plads. Desuden ser listen skræmmende tæt på hjemmet ud, når man sammenligner den med offentligt tilgængelige analyser af nyligt stjålne adgangskoder. Så: Uden krav om mindste passwordstyrke bruger 2 % af brugerne et af de 20 mest almindelige passwords. Det betyder: Hvis en angriber får bare 20 forsøg, vil 1 ud af 50 konti på dit websted kunne knækkes. For at forhindre dette kræver det, at man beregner entropien af et kodeord og derefter anvender en tærskelværdi. National Institute of Standards and Technology (NIST) Special Publication 800-63 har et sæt meget gode forslag. Det kan, når det kombineres med en ordbog og en analyse af tastaturlayoutet (f.eks. 'qwertyuiop' er et dårligt password), afvise 99 % af alle dårligt valgte passwords på et niveau på 18 bits entropi. Det er godt, men ikke tilstrækkeligt blot at beregne passwordstyrke og vise en visuel styrkeindikator til brugeren. Medmindre det håndhæves, vil mange brugere højst sandsynligt ignorere det. Og for et forfriskende bud på brugervenligheden af passwords med høj entropi kan Randall Munroe's Password Strength xkcd varmt anbefales. Brug Troy Hunt's Have I Been Pwned API til at tjekke brugernes adgangskoder mod adgangskoder, der er kompromitteret i offentlige databrud.

    DEL VI: Meget mere - eller: Forebyggelse af hurtige loginforsøg

    Først skal vi se på tallene: Password Recovery Speeds - Hvor længe kan dit password holde til det Hvis du ikke har tid til at kigge tabellerne i dette link igennem, er der her en liste over dem:

  3. Det tager næsten ingen tid at knække et svagt kodeord, selv hvis du knækker det med et regnestykke.
  4. Det tager næsten ingen tid at knække et alfanumerisk kodeord med 9 tegn, hvis det er hukommelsesuafhængigt.
  5. Det tager næsten ingen tid at knække en indviklet adgangskode med symboler, bogstaver og tal med store og små bogstaver, hvis den er mindre end 8 tegn lang (en stationær pc kan gennemsøge hele tastaturområdet op til 7 tegn i løbet af dage eller endda timer)
  6. Det ville imidlertid tage uforholdsmæssigt lang tid at knække selv et kodeord på 6 tegn, hvis man var begrænset til et forsøg i sekundet! Hvad kan vi så lære af disse tal? Ja, meget, men vi kan fokusere på den vigtigste del: det faktum, at det faktisk ikke er så svært at forhindre et stort antal hurtige, på hinanden følgende login-forsøg (dvs. brute force-angrebet). Men det er ikke så nemt at forhindre det rettigt, som det ser ud. Generelt set har du tre valgmuligheder, som alle er effektive mod brute-force-angreb (og ordbogsangreb, men da du allerede anvender en politik for stærke adgangskoder, bør de ikke være et problem):
  • Præsenter et CAPTCHA efter N mislykkede forsøg (irriterende som bare fanden og ofte ineffektivt -- men jeg gentager mig selv her)
  • Låse konti og kræve e-mailbekræftelse efter N mislykkede forsøg (dette er et DoS-angreb, der venter på at ske)
  • Og endelig login throttling: det vil sige at sætte en tidsforsinkelse mellem forsøg efter N mislykkede forsøg (ja, DoS-angreb er stadig mulige, men de er i det mindste langt mindre sandsynlige og meget mere komplicerede at gennemføre). Bedste praksis #1: En kort tidsforsinkelse, der øges med antallet af mislykkede forsøg, som f.eks:
  • 1 mislykket forsøg = ingen forsinkelse
  • 2 mislykkede forsøg = 2 sek. forsinkelse
  • 3 mislykkede forsøg = 4 sekunders forsinkelse
  • 4 mislykkede forsøg = 8 sekunders forsinkelse
  • 5 mislykkede forsøg = 16 sekunders forsinkelse
  • osv. DoS-angreb på denne ordning ville være meget upraktisk, da den resulterende spærretid er lidt større end summen af de tidligere spærretider. For at præcisere: Forsinkelsen er ikke en forsinkelse før returnering af svaret til browseren. Det er snarere en timeout- eller refraktærperiode, hvor loginforsøg til en bestemt konto eller fra en bestemt IP-adresse slet ikke accepteres eller evalueres. Det vil sige, at korrekte legitimationsoplysninger ikke vil give et vellykket login tilbage, og at forkerte legitimationsoplysninger ikke vil udløse en forøgelse af forsinkelsen. Bedste praksis #2: En mellemlang tidsforsinkelse, der træder i kraft efter N mislykkede forsøg, f.eks:
  • 1-4 mislykkede forsøg = ingen forsinkelse
  • 5 mislykkede forsøg = 15-30 minutters forsinkelse DoS-angreb på denne ordning ville være ret upraktisk, men bestemt muligt. Det kan også være relevant at bemærke, at en så lang forsinkelse kan være meget irriterende for en lovlig bruger. Glemte brugere vil ikke kunne lide dig. Bedste praksis #3: Kombinere de to tilgange - enten en fast, kort tidsforsinkelse, der træder i kraft efter N mislykkede forsøg, som f.eks:
  • 1-4 mislykkede forsøg = ingen forsinkelse
  • 5+ mislykkede forsøg = 20 sek. forsinkelse Eller en stigende forsinkelse med en fast øvre grænse, som f.eks:
  • 1 mislykket forsøg = 5 sekunders forsinkelse
  • 2 mislykkede forsøg = 15 sekunders forsinkelse
  • 3+ mislykkede forsøg = 45 sekunders forsinkelse Dette sidste skema stammer fra OWASP's forslag til bedste praksis (link 1 fra MUST-READ-listen) og bør betragtes som bedste praksis, selv om det ganske vist er restriktivt. *Som tommelfingerregel vil jeg dog sige: jo stærkere din passwordpolitik er, jo mindre skal du genere brugerne med forsinkelser. Hvis du kræver stærke (alfanumeriske alfanumeriske tegn med hensyn til store og små bogstaver + påkrævede tal og symboler) kodeord på 9+ tegn, kan du give brugerne 2-4 kodeordsforsøg uden forsinkelse, før du aktiverer neddrosling. DoS-angreb på denne endelige login-drosslingsordning ville være meget upraktisk. Og som en sidste detalje skal du altid tillade vedvarende (cookie-)logins (og/eller en CAPTCHA-verificeret login-formular) at passere igennem, så legitime brugere ikke engang bliver forsinket mens angrebet er i gang. På den måde bliver det meget upraktiske DoS-angreb til et ekstremt upraktisk angreb. Derudover giver det mening at lave mere aggressiv throttling på admin-konti, da det er de mest attraktive indgangspunkter

    DEL VII: Distribuerede brute force-angreb

    Som en sidebemærkning vil mere avancerede angribere forsøge at omgå login throttling ved at 'sprede deres aktiviteter':

  • at distribuere forsøgene på et botnet for at forhindre, at IP-adresser bliver markeret
  • I stedet for at vælge én bruger og prøve de 50.000 mest almindelige adgangskoder (hvilket de ikke kan, på grund af vores throttling), vil de vælge DEN mest almindelige adgangskode og prøve den mod 50.000 brugere i stedet. På den måde omgår de ikke blot foranstaltninger med maksimalt antal forsøg som CAPTCHA'er og login throttling, men deres chance for succes øges også, da det mest almindelige kodeord nummer 1 er langt mere sandsynligt end nummer 49.995
  • Spacing login-forespørgsler for hver brugerkonto, f.eks. med 30 sekunders mellemrum, for at snige sig under radaren Her ville den bedste praksis være at logge antallet af fejlslagne logins i hele systemet og bruge et løbende gennemsnit af dit websted som grundlag for en øvre grænse, som du derefter pålægger alle brugere. Er det for abstrakt? Lad mig omformulere: Lad os sige, at dit websted i gennemsnit har haft 120 dårlige logins om dagen i løbet af de sidste 3 måneder. Hvis du bruger dette (løbende gennemsnit), kan dit system sætte den globale grænse til 3 gange dette tal - dvs. 360 mislykkede forsøg i løbet af en 24-timers periode. Hvis det samlede antal mislykkede forsøg på tværs af alle konti så overstiger dette antal inden for en dag (eller endnu bedre, overvåge accelerationshastigheden og udløse på en beregnet tærskel), aktiverer det systemdækkende login throttling - hvilket betyder korte forsinkelser for ALLE brugere (stadig med undtagelse af cookie-logins og/eller backup CAPTCHA-logins). Jeg har også postet et spørgsmål med flere detaljer og en rigtig god diskussion af, hvordan man undgår tricky pitfals i afværgelsen af distribuerede brute force-angreb

    DEL VIII: To-faktor-autentifikation og autentifikationsudbydere

    Legitimationsoplysninger kan blive kompromitteret, hvad enten det er ved udnyttelse, ved at adgangskoder skrives ned og tabes, ved at bærbare computere med nøgler stjæles, eller ved at brugere indtaster logins på phishing-websteder. Logins kan beskyttes yderligere med to-faktor-autentifikation, som anvender out-of-band-faktorer som f.eks. engangskoder, der modtages via et telefonopkald, en sms-besked, en app eller en dongle. Flere udbydere tilbyder to-faktor-autentificeringstjenester. Autentificering kan uddelegeres fuldstændigt til en tjeneste med en enkelt sign-on-tjeneste, hvor en anden udbyder håndterer indsamling af legitimationsoplysninger. Dette skubber problemet til en betroet tredjepart. Google og Twitter tilbyder begge standardbaserede SSO-tjenester, mens Facebook tilbyder en lignende proprietær løsning.

    MUST-READ LINKS Om webgodkendelse

  1. OWASP Guide To Authentication / OWASP Authentication Cheat Sheet
  2. Dos and Don'ts of Client Authentication on the Web (meget læseværdig MIT research paper)
  3. Wikipedia: HTTP cookie
  4. Personlige vidensspørgsmål til fallback-autentifikation: Security questions in the era of Facebook (meget læseværdigt Berkeley research paper)
Kommentarer (70)

Endelig artikel

Afsendelse af legitimationsoplysninger

Den eneste praktiske måde at sende legitimationsoplysninger 100 % sikkert på er ved at bruge [SSL][1]. Det er ikke sikkert at bruge JavaScript til at hashe kodeordet. Almindelige faldgruber for klient-side password hashing:

  • Hvis forbindelsen mellem klient og server er ukrypteret, er alt, hvad du gør, [sårbart over for man-in-the-middle-angreb][2]. En angriber kunne erstatte det indkommende javascript for at bryde hashing eller sende alle legitimationsoplysninger til deres server, de kunne lytte til klientens svar og udgive sig for at være brugerens perfekte identitet osv. osv. osv. SSL med betroede certifikatudstedere er designet til at forhindre MitM-angreb.
  • Den hashede adgangskode, som serveren modtager, er [mindre sikker][3], hvis du ikke gør yderligere, overflødigt arbejde på serveren. Der findes en anden sikker metode kaldet SRP, men den er patenteret (selv om den er [frit licenseret][4]), og der er kun få gode implementeringer til rådighed.

    Lagring af adgangskoder

    Du må aldrig gemme adgangskoder som klartekst i databasen. Ikke engang hvis du er ligeglad med sikkerheden på dit eget websted. Antag, at nogle af dine brugere vil genbruge adgangskoden til deres online bankkonto. Så gem den hashede adgangskode og smid den originale væk. Og sørg for, at adgangskoden ikke vises i adgangslogfiler eller programlogfiler. OWASP anbefaler brugen af Argon2 som dit første valg for nye applikationer. Hvis dette ikke er tilgængeligt, bør PBKDF2 eller scrypt bruges i stedet. Og endelig, hvis ingen af de ovennævnte er tilgængelige, skal du bruge bcrypt. Hashes i sig selv er også usikre. F.eks. betyder identiske passwords identiske hashes - dette gør hash-opslagstabeller til en effektiv måde at knække mange passwords på én gang. Gem i stedet den saltede hash. En salt er en streng, der tilføjes til adgangskoden før hashing - brug en anden (tilfældig) salt pr. bruger. Saltet er en offentlig værdi, så du kan gemme dem sammen med hash'en i databasen. Se her for mere om dette. Det betyder at du ikke kan sende brugeren deres glemte passwords (fordi du kun har hash'en). Du må ikke nulstille brugerens adgangskode, medmindre du har autentificeret brugeren (brugerne skal bevise, at de kan læse e-mails, der sendes til den gemte (og validerede) e-mailadresse).

    Sikkerhedsspørgsmål

    Sikkerhedsspørgsmål er usikre - undgå at bruge dem. Hvorfor? Alt, hvad et sikkerhedsspørgsmål kan, kan en adgangskode gøre bedre. Læs PART III: Brug af hemmelige spørgsmål i [@Jens Roland svar][6] her i denne wiki.

    Sessionscookies

    Når brugeren logger ind, sender serveren brugeren en session cookie. Serveren kan hente brugernavnet eller id'et fra cookien, men ingen andre kan generere en sådan cookie (TODO forklarer mekanismer). [Cookies kan kapres][7]: de er kun lige så sikre som resten af klientens maskine og anden kommunikation. De kan læses fra disken, sniffes i netværkstrafikken, tages fra et cross-site scripting-angreb, phished fra en forgiftet DNS, så klienten sender sine cookies til de forkerte servere. Send ikke vedvarende cookies. Cookies bør udløbe ved afslutningen af klientsessionen (lukning af browseren eller når du forlader dit domæne). Hvis du ønsker at autologinere dine brugere, kan du indstille en vedvarende cookie, men den skal være adskilt fra en cookie for hele sessionen. Du kan indstille et ekstra flag om, at brugeren er automatisk logget ind og skal logge ind for alvor ved følsomme operationer. Dette er populært blandt shoppingwebsteder, der ønsker at give dig en problemfri, personlig shoppingoplevelse, men stadig beskytte dine finansielle oplysninger. Når du f.eks. vender tilbage til Amazon, viser de dig en side, der ser ud som om du er logget ind, men når du vil afgive en ordre (eller ændre din leveringsadresse, dit kreditkort osv.), beder de dig om at bekræfte din adgangskode. Finansielle websteder som banker og kreditkort har på den anden side kun følsomme data og bør ikke tillade automatisk logon eller en lavsikkerhedstilstand.

    Liste over eksterne ressourcer

Kommentarer (5)

Først et kraftigt advarsel om, at dette svar ikke passer bedst til netop dette spørgsmål. Det bør bestemt ikke være det bedste svar!

Jeg vil gå videre og nævne Mozillas foreslåede BrowserID (eller måske mere præcist Verified Email Protocol) i en ånd af at finde en opgraderingsvej til bedre tilgange til autentificering i fremtiden.

Jeg vil opsummere det på denne måde:

  1. Mozilla er en nonprofitorganisation med værdier, der stemmer godt overens med at finde gode løsninger på dette problem.
  2. Virkeligheden i dag er, at de fleste websteder bruger formularbaseret autentificering
  3. Formularbaseret autentifikation har en stor ulempe, nemlig en øget risiko for phishing. Brugerne bliver bedt om at indtaste følsomme oplysninger i et område, der kontrolleres af en ekstern enhed, i stedet for et område, der kontrolleres af deres brugeragent (browser).
  4. Da browsere er implicit betroede (hele idéen med en brugeragent er at handle på brugerens vegne), kan de bidrage til at forbedre denne situation.
  5. Den primære kraft, der bremser fremskridt her, er deployment deadlock. Løsningerne skal nedbrydes i trin, som i sig selv giver en vis inkrementel fordel.
  6. Den enkleste decentraliserede metode til at udtrykke en identitet, der er indbygget i internetinfrastrukturen, er domænenavnet.
  7. Som et andet niveau for at udtrykke identitet forvalter hvert domæne sit eget sæt konti.
  8. Formen "account@domain" er kortfattet og understøttes af en lang række protokoller og URI-ordninger. En sådan identifikator er naturligvis mest universelt anerkendt som en e-mail-adresse.
  9. E-mail-udbydere er allerede de-facto de primære identitetsudbydere online. De nuværende strømme til nulstilling af adgangskoder giver normalt mulighed for at tage kontrol over en konto, hvis man kan bevise, at man kontrollerer den pågældende kontos tilknyttede e-mail-adresse.
  10. Verified Email Protocol blev foreslået for at tilvejebringe en sikker metode baseret på kryptografi med offentlige nøgler til at strømline processen med at bevise over for domæne B, at du har en konto på domæne A.
  11. For browsere, der ikke understøtter Verified Email Protocol (i øjeblikket alle), tilbyder Mozilla en shim, der implementerer protokollen i JavaScript-kode på klientsiden.
  12. For e-mailtjenester, der ikke understøtter Verified Email Protocol, giver protokollen tredjeparter mulighed for at fungere som en betroet mellemmand, der hævder, at de har verificeret en brugers ejerskab af en konto. Det er ikke ønskeligt at have et stort antal af sådanne tredjeparter; denne mulighed er kun beregnet til at muliggøre en opgraderingsvej, og det er langt at foretrække, at e-mailtjenesterne selv leverer disse bekræftelser.
  13. Mozilla tilbyder deres egen tjeneste til at fungere som en sådan betroet tredjepart. Tjenesteudbydere (dvs. Relying Parties), der implementerer Verified Email Protocol, kan vælge at stole på Mozilla's assertions eller ej. Mozillas tjeneste verificerer brugernes kontoejerskab ved hjælp af den konventionelle metode, hvor der sendes en e-mail med et bekræftelseslink.
    1. Tjenesteudbydere kan naturligvis tilbyde denne protokol som en mulighed ud over andre autentifikationsmetoder, som de måtte ønske at tilbyde.
  14. En stor brugergrænsefladefordel, der søges opnået her, er "identitetsvælgeren". Når en bruger besøger et websted og vælger at autentificere sig, viser hans browser ham et udvalg af e-mail-adresser ("personlig", "arbejde", "politisk aktivisme" osv.), som han kan bruge til at identificere sig over for webstedet.
  15. En anden stor brugergrænsefladefordel, der søges opnået som en del af denne indsats, er at hjælpe browseren med at få mere at vide om brugerens session - hvem de er logget ind som i øjeblikket, primært - så den kan vise det i browserens chrome.
  16. På grund af systemets distribuerede karakter undgår det at være låst fast til store websteder som Facebook, Twitter, Google osv. Enhver person kan eje sit eget domæne og dermed fungere som sin egen identitetsudbyder.

Dette er ikke strengt taget "formularbaseret autentificering til websteder". Men det er et forsøg på at gå fra den nuværende norm med formularbaseret autentificering til noget mere sikkert: browserstøttet autentificering.

Kommentarer (2)