Gå til innhold

Sjekkeliste for login scripts


Anbefalte innlegg

Hei

 

Når en lager loginscripts er det oftest mye en glemmer av som kan bli benyttet av, adjektivet som programmer.no så flittig bruker, ondisnnede-brukere. Tenkte at det hadde vært litt greit om vi kunne ha laget en liste over viktige aspekter når vi lager login scripts.

 

Tanken er at vi kan lære fra hverandre når det gjelder sikkerhet, forkorte listen under, forlenge listen, forklare hvorfor et punkt burde være der, hvorfor et punkt ikke burde være der eller komme med bedre/alternative metoder for det samme.

 

Jeg kan godt begynne (kan ikke huske helt hvorfor men har lest en del artikkler om sikkerhet, og mye hørtest fornuftig ut, selvom jeg ikke forsto alt):

  1. Ikke valider en login med å bare sjekke $_SESSION["login"] == true osv. Dette er usikkert. Send heller passord og brukernavn videre i sessjonen for så og validere for hver gang.
  2. Bruk salting! 6731918[/snapback]
  3. Ikke bare sjekke brukernavn og passord. Skriv innlogginstida og ip, og sjekke om ipen stemmer (dette er for å hindre session hijacking, leste om det i en artikkel) og om tida er innenfor en bestemt timeout. (mulig dette er fiksbart med session_cache_expire, er ikke sikker). Også burde du sjekke $_SERVER['HTTP_USER_AGENT'] i tillegg (ikke glem å hashe alt).
  4. Ikke ha en $_SESSION["password"] som inneholder passordet, ha heller $_SESSION["md5password"] hvor passordet er hashet i md5.
  5. Bruk addslashes(); eller mysql_real_escape(); for å fjerne farlige tegn fra input-ene (brukernavn og passord). Dette er for å unngå eventuelle problemer med MySQL queries
  6. legg inn en sleep(10); hvis innlogingen ikke validerer. dette er for å begrense "hammering".

håper noen har lyst å bygge videre på listen sånn at vi php-hobbyister kan lage noe bra!

 

kommentarer til listen er også velkomne! :)

 

 

 

Eksempel på login script:

Hotstian: 5727461[/snapback] (bruker MySQL)

 

 

 

Fjernet fra listen:

 

 

 

(md5 og sha1 er relativt svake krypteringer (vi venter forsatt på at sha256 skal integreres i php), men frem til da krypter passordet i både sha1 og md5. Ikke krypter i md5 også krypter i sha1, men ha heller to variabler i sesjonen hvor den ene er passordet kryptert i sha1 og den andre i md5. Da må det riktige passordet lagres i begge krypteringene.)

 

 

 

Endret av MC2
Lenke til kommentar
Videoannonse
Annonse
md5 og sha1 er relativt svake krypteringer (vi venter forsatt på at sha256 skal integreres i php), men frem til da krypter passordet i både sha1 og md5. Ikke krypter i md5 også krypter i sha1, men ha heller to variabler i sesjonen hvor den ene er passordet kryptert i sha1 og den andre i md5. Da må det riktige passordet lagres i begge krypteringene.

5724029[/snapback]

Hva er tankegangen bak det her? At man skal gi angriper friheten til å velge mellom md5 og sha1?

Endret av Ernie
Lenke til kommentar
Hva er tankegangen bak det her? At man skal gi angriper friheten til å velge mellom md5 og sha1?

 

Hmm.. han tenke vel at du kan sjekke om passordet stemmer mot begge strengene. Slik at angriperen må finne et passord som passer til begge kryptering metodene. I grunn ganske lurt.

Lenke til kommentar

Skrev han ikke at scriptet burde skjekke både ett md5 krypert passord og det samme passordet som sha1 krypert..

 

$md5passord = "5dss6ew8es15d56se8axvr8";

$sha1passord = "sd8e2d48w5d258wxcv8es2";

 

Altså skjekke begge disse, selv om de i prinsippet er det samme passordet.

(PS: det er ikke noe ekte krypering det jeg skrev, jeg bare trykte vilt på tastaturet ;) )

Lenke til kommentar
Hva er tankegangen bak det her? At man skal gi angriper friheten til å velge mellom md5 og sha1?

 

Hmm.. han tenke vel at du kan sjekke om passordet stemmer mot begge strengene. Slik at angriperen må finne et passord som passer til begge kryptering metodene. I grunn ganske lurt.

5724314[/snapback]

I grunn ganske dumt, siden man gjør noe tilsynelatende ubrukelig. Greia er at man skal beskytte seg mot bruteforce og da kommer man frem til passordet i klartekst. Da hjelper det svært lite med både md5 og sha1 hver for seg eller i kombinasjon. Eneste beskyttelsen man har er lange passord, og det er bokstavligtalt eneste. Ja, med mindre du vil bruke en steintung hash-algoritme da, men det gir fort problemer med ytelsen.

 

Edit: Med lange passord mener jeg 8 eller flere tegn. Da vil det ta såpass med tid at ingen gidder med det første.

Endret av Ernie
Lenke til kommentar
Hva er tankegangen bak det her? At man skal gi angriper friheten til å velge mellom md5 og sha1?

 

Hmm.. han tenke vel at du kan sjekke om passordet stemmer mot begge strengene. Slik at angriperen må finne et passord som passer til begge kryptering metodene. I grunn ganske lurt.

5724314[/snapback]

I grunn ganske dumt, siden man gjør noe tilsynelatende ubrukelig. Greia er at man skal beskytte seg mot bruteforce og da kommer man frem til passordet i klartekst. Da hjelper det svært lite med både md5 og sha1 hver for seg eller i kombinasjon. Eneste beskyttelsen man har er lange passord, og det er bokstavligtalt eneste. Ja, med mindre du vil bruke en steintung hash-algoritme da, men det gir fort problemer med ytelsen.

 

Edit: Med lange passord mener jeg 8 eller flere tegn. Da vil det ta såpass med tid at ingen gidder med det første.

5724337[/snapback]

 

Ikke enig, hvis du kryptere en tekst med md5 blir kan den krypterte teksten bli flere 1000 tegn lang. ( selv om teksten bare er på noen tegn). Men i PHP får du bare ut de første 35 (?) tegnene. dvs at hvis du krypterer "Mittpassord" og "dittpassord" så kan du faktisk få samme md5 strengen tilbake. selv om den krypterte teksten ikke er lik.

 

Men hvis du kontrollere passord mot sha1 og md5 vil det vel være nesten umulig å lure seg inn slik.

 

Men hva vet vel jeg...

Lenke til kommentar
Hva er tankegangen bak det her? At man skal gi angriper friheten til å velge mellom md5 og sha1?

 

Hmm.. han tenke vel at du kan sjekke om passordet stemmer mot begge strengene. Slik at angriperen må finne et passord som passer til begge kryptering metodene. I grunn ganske lurt.

5724314[/snapback]

I grunn ganske dumt, siden man gjør noe tilsynelatende ubrukelig. Greia er at man skal beskytte seg mot bruteforce og da kommer man frem til passordet i klartekst. Da hjelper det svært lite med både md5 og sha1 hver for seg eller i kombinasjon. Eneste beskyttelsen man har er lange passord, og det er bokstavligtalt eneste. Ja, med mindre du vil bruke en steintung hash-algoritme da, men det gir fort problemer med ytelsen.

 

Edit: Med lange passord mener jeg 8 eller flere tegn. Da vil det ta såpass med tid at ingen gidder med det første.

5724337[/snapback]

 

Ikke enig, hvis du kryptere en tekst med md5 blir kan den krypterte teksten bli flere 1000 tegn lang. ( selv om teksten bare er på noen tegn). Men i PHP får du bare ut de første 35 (?) tegnene. dvs at hvis du krypterer "Mittpassord" og "dittpassord" så kan du faktisk få samme md5 strengen tilbake. selv om den krypterte teksten ikke er lik.

 

Men hvis du kontrollere passord mot sha1 og md5 vil det vel være nesten umulig å lure seg inn slik.

 

Men hva vet vel jeg...

5724397[/snapback]

Nei hva veit du ... En streng i PHP kan være langt lengre enn 35 tegn, og det er en statistisk usannsynlighet at man får collision med de passordene de fleste vil bruke. Rettere sagt er sannsynligheten fraværende og overhode ikke verdt å tenke på.

 

Edit:

md5('abcdeabcdeabcdeabcdeabcdeabcdeabcde') = 306e85bcb6c9a12b22b440b2f0f991b1

md5('abcdeabcdeabcdeabcdeabcdeabcdeabcdea') = a26a61771ce6a88e41d9fcad55bcbcf1

 

Den første er på eksakt 35 tegn, den andre på 36. Som du ser er det en forskjell.

Endret av Ernie
Lenke til kommentar
Nei hva veit du ... En streng i PHP kan være langt lengre enn 35 tegn, og det er en statistisk usannsynlighet at man får collision med de passordene de fleste vil bruke. Rettere sagt er sannsynligheten fraværende og overhode ikke verdt å tenke på.

 

Edit:

md5('abcdeabcdeabcdeabcdeabcdeabcdeabcde') = 306e85bcb6c9a12b22b440b2f0f991b1

md5('abcdeabcdeabcdeabcdeabcdeabcdeabcdea') = a26a61771ce6a88e41d9fcad55bcbcf1

 

Den første er på eksakt 35 tegn, den andre på 36. Som du ser er det en forskjell.

5724425[/snapback]

 

Hmm.. når jeg snakker om md5 strengen, mener jeg den du får tilbake, IKKE den du putter inn.. den som kommer ut er på 32 tegn ser det ut til. Samme hvor mye du putter inn.

 

Dvs at du du har muligheten til å få tilbake samme md5 strengen på forskjellige ting du krypterer.

Lenke til kommentar
Nei hva veit du ... En streng i PHP kan være langt lengre enn 35 tegn, og det er en statistisk usannsynlighet at man får collision med de passordene de fleste vil bruke. Rettere sagt er sannsynligheten fraværende og overhode ikke verdt å tenke på.

 

Edit:

md5('abcdeabcdeabcdeabcdeabcdeabcdeabcde') = 306e85bcb6c9a12b22b440b2f0f991b1

md5('abcdeabcdeabcdeabcdeabcdeabcdeabcdea') = a26a61771ce6a88e41d9fcad55bcbcf1

 

Den første er på eksakt 35 tegn, den andre på 36. Som du ser er det en forskjell.

5724425[/snapback]

 

Hmm.. når jeg snakker om md5 strengen, mener jeg den du får tilbake, IKKE den du putter inn.. den som kommer ut er på 32 tegn ser det ut til. Samme hvor mye du putter inn.

 

Dvs at du du har muligheten til å få tilbake samme md5 strengen på forskjellige ting du krypterer.

5724479[/snapback]

... og poenget er? 2^128 er antall kobinasjoner man har. Det er mye og collision vil ikke oppstå før du har et rimelig heftig langt passord, noe ytterst få har, om noen. Men for all del. Hvis du skal sikre det mot det ene tilfellet som kanskje oppstår blandt x millioner tilfeller så "go ahead", men da finnes det plenty med andre ting du ikke har tatt hensyn til. F.eks innbrudd i databasen, webserver, lytting på trafikken osv.

Endret av Ernie
Lenke til kommentar

tror dere har delvis misforstått hva tordnes mener. Altså forstill deg at du har en encryptor som heter ape og en som heter kake.

 

Så encrypter du:

ape("hello") = "jeg er en banan";

ape("wohooa") = "jeg er en appelsin";

 

de to stregnene som blir retunert av enkryptorene er forskjellige, men pga (som jeg forsto det) php sine begrensninger gir den bare ut et viss antall characters, dermed blir de enkryptede strengen kappet ned til "jeg er en ", og dermed er de krypterte og forkortede strengene av to forskjellige passord lik hverandre, altså de blir forkortet til dette:

ape("hello") = "jeg er en "; // king kong sin konto

ape("wohooa") = "jeg er en "; // donald sin konto

 

men dersom du bruker en annen enkryptor som bruker en annen algoritme og krypterer passordene

kake("hello") = "howdy ho ho ho";

kake("wohooa") = "die snow man";

men på grunn av tilsvarende begrensninger blir disse enkryptede strenge også kappet ned, og blir til:

kake("hello") = "howdy ho"; // king kong sin konto

kake("wohooa") = "die snow "; // donald sin konto

og som du ser er disse to ikke samme.

 

Så da kommer vi til problemet, når kan vi vite når man skal bruke den ene algortimen eller den andre for å få to unike enkryptions? Jo man sjekker begge.

Om man ikke hadde sjekket begge kunne dette ha sjedd:

King Kong skriver inn Donald sitt bruker navn, men skriver inn sitt eget passord, og han kommer dermed inn på Donald sin konto. Altså Donald sin konto informasjon ser sånn ut:

$username = "Donald";

$password = ape("wohooa") = "jeg er en "; // fordi den blir forkortet, forklart over

 

mens King Kong sin konto ser sånn ut:

$username = "King Kong";

$password = ape("hello") = "jeg er en ";

 

og hvis King Kong skriver inn Donald sitt brukernavn og sitt eget passord vil han komme inn på Donald sin konto.

Men hvis man også bruker kake algoritmen blir kontoene seende sånn ut:

$username = "Donald";

$password = ape("wohooa") = "jeg er en ";

$password2 = kake("wohooa") = "die snow ";

 

mens King Kong sin konto ser sånn ut:

$username = "King Kong";

$password = ape("hello") = "jeg er en ";

$password2 = kake("hello") = "howdy ho";

 

og dermed vil ikke King Kong sitt ondsinnet forsøk på å komme inn på Donald sin konto med sitt eget passord lykkes.

 

Noen som forstår? Eller forsto jeg trones riktig?

Lenke til kommentar

Tror du har misforstått veldig her jeg. Både md5 og sha1 returnerer en binærstreng som konverteres til hex bare for lesbarehetensskyld (hvem gidder å lese 128 og 160 bit?). Dette er uavhengig av språk og ikke spesifikt til PHP. Det problemet du forsøker å omtale her er noe man kalle collision. Det inntreffer når to strenger får samme hash. Det er teoretisk mulig, men så usannsynlig at det er ingen som tar hensyn til det. Vi snakker her om at hash-en til tegnet a kanskje krasjer med en streng på rundt 110-120 tegn, og da mest sannsynligvis en streng som ikke gir mening for noen.

Endret av Ernie
Lenke til kommentar
tror dere har delvis misforstått hva tordnes mener. Altså forstill deg at du har en encryptor som heter ape og en som heter kake.

 

Så encrypter du:

ape("hello") = "jeg er en banan";

ape("wohooa") = "jeg er en appelsin";

 

de to stregnene som blir retunert av enkryptorene er forskjellige, men pga (som jeg forsto det) php sine begrensninger gir den bare ut et viss antall characters, dermed blir de enkryptede strengen kappet ned til "jeg er en ", og dermed er de krypterte og forkortede strengene av to forskjellige passord lik hverandre, altså de blir forkortet til dette:

ape("hello") = "jeg er en ";              // king kong sin konto

ape("wohooa") = "jeg er en ";          // donald sin konto

 

( går ut i fra at jeg er "trodnes" :)

 

Nei, du missforsto litt her. Teksten som blir kjørt gjennom md5() bli ikke kuttet, men det du får tilbake er kuttet.

 

En annen ting, jeg håper du virkelig sjekker passord mot brukeren og ikke bare om passordet stemmer med et hvilken som helst annen passord som er registert i systemet.

 

Ha en fortsatt fin da

g

Lenke til kommentar
Nei, du missforsto litt her. Teksten som blir kjørt gjennom md5() bli ikke kuttet, men det du får tilbake er kuttet.

5725091[/snapback]

Det som kommer ut blir da overhode ikke kuttet det heller da. Hash-algoritmene returnerer x bit uavhengig av lengden på teksten inn. Det er liksom noe av poenget med hash.

Lenke til kommentar
( går ut i fra at jeg er "trodnes" :)

 

Nei, du missforsto litt her. Teksten som blir kjørt gjennom md5() bli ikke kuttet, men det du får tilbake er kuttet.

 

En annen ting, jeg håper du virkelig sjekker passord mot brukeren og ikke bare om passordet stemmer med et hvilken som helst annen passord som er registert i systemet.

 

Ha en fortsatt fin da

g

5725091[/snapback]

jupp, jeg sjekker om passordet stemmer med brukernavnet som er gitt.

 

angående det andre, er det ikke det jeg ment da? atlså den uleselige strengen som kommer ut blir kappet ned til 32 (?) characters, dermed har du muligheten for at flere passord får samme hash?

Lenke til kommentar

Da blir vel konklusjonen at det bare er nødvendig med en kryptering (jeg velger iallfall å stole på Ernie her, og har heller aldri sett noen andre som har sagt noe om å ha to krypteringer av samme passord). Men dette skulle vel være en tråd hvor man slang ut tips for å sikre login-scripts?

En ting som vel er ganske viktig er å fjerne alle farlige tegn fra inputen i login-formen. Noen gode råd til hvordan man gjør dette sikrest mulig når man har et MySQL-loginsystem?

Lenke til kommentar
Nei, du missforsto litt her. Teksten som blir kjørt gjennom md5() bli ikke kuttet, men det du får tilbake er kuttet.

5725091[/snapback]

Det som kommer ut blir da overhode ikke kuttet det heller da. Hash-algoritmene returnerer x bit uavhengig av lengden på teksten inn. Det er liksom noe av poenget med hash.

5725102[/snapback]

 

Hehe.. men da har jeg jo lært noe i dag også da ;)

Lenke til kommentar
En ting som vel er ganske viktig er å fjerne alle farlige tegn fra inputen i login-formen. Noen gode råd til hvordan man gjør dette sikrest mulig når man har et MySQL-loginsystem?

5725154[/snapback]

 

addslashes() skulle vel være nok?

Lenke til kommentar

Ok. Men det bør iallfall opp på sjekklisten da, å pakke inn i addslashes() eller lignende.

Hva er forresten forskjellen på addslashes() og mysql_real_escape() ? Gjør de akkurat det samme?

 

edit:

[*]Ikke bare sjekke brukernavn og passord. Skriv innlogginstida og ip, og sjekke om ipen stemmer (dette er for å hindre session hijacking, leste om det i en artikkel) og om tida er innenfor en bestemt timeout. (mulig dette er fiksbart med session_cache_expire, er ikke sikker)

5724029[/snapback]

Så at Ernie (tror jeg det var) skrev en annen plass at det også var lurt å sjekke ting som browser osv. Vet ikke hvor mye sikkerhet det gir med sånne småting akkurat, men kan kanskje være verdt å ta med.

Endret av anners
Lenke til kommentar

ok, har lagt til det over.

 

mener du useragent?

 

et annet punkt. burde man ikke legge til en sleep(); når brukeren skriver inn feil passord eller brukernavn eller er dette bare unødvendig? I så fall, hvor mange sekunder burde den være? 10?

Endret av MC2
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...