[php, mysql] Hoe website beveiligen?

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Maaark
  • Registratie: Juli 2008
  • Laatst online: 02-06 11:35
Hallo Tweakers,

Voor een nieuw te maken website heb ik een aantal vragen of ik eigenlijk wel goed bezig ben qua beveiliging. Ik zal mijn vragen eventjes opsommen:


- Is het gebruiken van een sleep() bij het inloggen noodzakelijk? Aangezien het liefst alles natuurlijk zo snel mogelijk moet gaan?


- Hoeveel mislukte inlog pogingen zijn normaal voordat er een tijdelijk ban word uitgedeeld?


- Momenteel gebruik ik altijd 2 sessions om te bepalen of ik ook wel echt met de gebruiker te maken heb, een session id, met het userid, en een session met een random waarde die ook in de database opgeslagen is na het inloggen. Bij elke pagina opvraag controleer ik of het userid en de random waarde overeen komen met de waardes in de database en mocht dit niet het geval zijn word de gebruiker uitgelogd. Is deze opzet goed?


- Opslaan van wachtwoorden:
Hoe kan dit het veiligste? Nu gebruik ik altijd nog gewoon md5 ervoor, maar is het handig om bijvoorbeeld de md5 waarde te pakken en dan per user een aantal unieke tekens achter elkaar te zetten en die aan de md5 plakken en daar een sha1 van te maken?


- Opslaan van email adressen:
Is het verstandig om de email adressen te coderen via een encryption key? En dan het email adres bij registratie te versleutelen met deze key en als het email adres nodig is deze te dectypten?


- Mis ik nog beveiligingsfunctie’s die echt niet mogen ontbreken?

Alvast bedankt

Acties:
  • 0 Henk 'm!

  • beany
  • Registratie: Juni 2001
  • Laatst online: 09:34

beany

Meeheheheheh

- Hoeveel mislukte inlog pogingen zijn normaal voordat er een tijdelijk ban word uitgedeeld?
3

Maar je kan ook gaan vertragen.
1x foute login = 0 seconden wachttijd voor volgende poging is toegestaan
2e keer foute login = 3 seconden
3e keer foute login = 9 seconden
4e keer foute login = 28 seconden
etc

Dagelijkse stats bronnen: https://x.com/GeneralStaffUA en https://www.facebook.com/GeneralStaff.ua


Acties:
  • 0 Henk 'm!

  • ReenL
  • Registratie: Augustus 2010
  • Laatst online: 14-09-2022
"Is het gebruiken van een sleep() bij het inloggen noodzakelijk? Aangezien het liefst alles natuurlijk zo snel mogelijk moet gaan?"
Let op dat je dit dan ook bij een gelukte login moet doen. Anders kan een bot elke response die langer dan een halve seconde duurt negeren en een nieuwe request sturen en de response simpel negeren.

Een alternatief is het aantal pogingen per account per uur vast zetten. Zo kan een bot hoogstens alle accounts (tijdelijk) locken.

"Hoeveel mislukte inlog pogingen zijn normaal voordat er een tijdelijk ban word uitgedeeld?"
Op welke basis wil je bannen? IP? Account?

"Momenteel gebruik ik altijd 2 sessions om te bepalen of ik ook wel echt met de gebruiker te maken heb"
Je bedoeld 2 cookies? Als de ene cookie gestolen wordt, is het geen kunst om de andere mee te nemen. Je voorkomt wel dat iemand de SessionId kan brute forcen. Iets wat in php makkelijker blijkt te zijn dan mensen denken. Echter zou ik niet het userId gebruiken, die is te voorspelbaar.

"Opslaan van wachtwoorden"
Nee! geen md5+sha of md5+md5. Je maakt namelijk de input voor de 2e ronde voorspelbaar. Als je het veilig wilt, maak voor elke gebruiker een random seed aan (20+ chars) doe die samen met het wachtwoord in een sha512.
Ten eerste is het aantal rainbow tables van sha512 nihil (en door de grote seed onbruikbaar) en ten tweede zorg je met de random seed ervoor dat een brute forcer die de database in zijn bezit heeft, voor elke user opnieuw moet beginnen.

"Opslaan van email adressen"
Waarom? Een lijst met e-mail addressen is tegenwoordig niet moeilijk te krijgen. Waarom moeite doen om het te beveiligen? Plus als iemand toegang tot je server heeft kan die ook bij de sleutel. En alleen SQL toegang hebben is lastig als je een goeie abstractielaag gebruikt en niet je queries met de hand schrijft.

"Mis ik nog beveiligingsfunctie’s die echt niet mogen ontbreken?"
De db abstractie laag :). Plus ik ben benieuwd wat er in de database staat wat het zo veilig moet maken. Credit card gegevens? Want dan kan ik nog wel een uurtje doorgaan ;)

[ Voor 6% gewijzigd door ReenL op 27-01-2011 21:08 ]


Acties:
  • 0 Henk 'm!

  • sloth
  • Registratie: Januari 2010
  • Niet online
Wat wachtwoorden betreft kan je best een salt gebruiken.

Zo heeft het voor een hacker geen zin om een standaard md5 rainbowtable er op los te laten.

Acties:
  • 0 Henk 'm!

  • Maaark
  • Registratie: Juli 2008
  • Laatst online: 02-06 11:35
@beany: Dat is inderdaad een goed plan :) Alleen heb ik zelf ook wel eens dat ik 10x moet raden welk wachtwoord ik gebruik... dan zou deze sleep tijd een beetje erg onvriendelijk zijn?
ReenL schreef op donderdag 27 januari 2011 @ 21:06:
"Is het gebruiken van een sleep() bij het inloggen noodzakelijk? Aangezien het liefst alles natuurlijk zo snel mogelijk moet gaan?"
Let op dat je dit dan ook bij een gelukte login moet doen. Anders kan een bot elke response die langer dan een halve seconde duurt negeren en een nieuwe request sturen en de response simpel negeren.

Een alternatief is het aantal pogingen per account per uur vast zetten. Zo kan een bot hoogstens alle accounts (tijdelijk) locken.

"Hoeveel mislukte inlog pogingen zijn normaal voordat er een tijdelijk ban word uitgedeeld?"
Op welke basis wil je bannen? IP? Account?

"Momenteel gebruik ik altijd 2 sessions om te bepalen of ik ook wel echt met de gebruiker te maken heb"
Je bedoeld 2 cookies? Als de ene cookie gestolen wordt, is het geen kunst om de andere mee te nemen. Je voorkomt wel dat iemand de SessionId kan brute forcen. Iets wat in php makkelijker blijkt te zijn dan mensen denken. Echter zou ik niet het userId gebruiken, die is te voorspelbaar.

"Opslaan van wachtwoorden"
Nee! geen md5+sha of md5+md5. Je maakt namelijk de input voor de 2e ronde voorspelbaar. Als je het veilig wilt, maak voor elke gebruiker een random seed aan (20+ chars) doe die samen met het wachtwoord in een sha512.
Ten eerste is het aantal rainbow tables van sha512 nihil (en door de grote seed onbruikbaar) en ten tweede zorg je met de random seed ervoor dat een brute forcer die de database in zijn bezit heeft, voor elke user opnieuw moet beginnen.

"Opslaan van email adressen"
Waarom? Een lijst met e-mail addressen is tegenwoordig niet moeilijk te krijgen. Waarom moeite doen om het te beveiligen? Plus als iemand toegang tot je server heeft kan die ook bij de sleutel. En alleen SQL toegang hebben is lastig als je een goeie abstractielaag gebruikt en niet je queries met de hand schrijft.

"Mis ik nog beveiligingsfunctie’s die echt niet mogen ontbreken?"
De db abstractie laag :). Plus ik ben benieuwd wat er in de database staat wat het zo veilig moet maken. Credit card gegevens? Want dan kan ik nog wel een uurtje doorgaan ;)
toon volledige bericht
Ik wil bij de inlogpogingen liever het ip adres blokkeren, als ik tijdelijk een account blokkeer ben ik bang dat ik straks een site heb waar niemand meer kan inloggen.. Over het altijd sleep() toepassen was ik al van op de hoogte, maar bedankt.

Ik bedoel geen cookie's, $_SESSION[waarde] gebruik ik, ik gebruik session id omdat het zo handig is om query's te doen :)

Over de email adressen: mooi, dan kan ik dat achterwegen laten, scheelt weer :)

Over de db abstractie laag, ik ben van plan om codeigniter te gaan gebruiken, zit die daar standaard in? Ook wil ik in codeingiter als "dbdriver" mysqli gaan gebruiken, maakt dat ook verschil uit?

Ik ga niet echt belangrijke data opslaan, ik wil er alleen zeker van zijn dat ik het juist doe en niet nalatig ben geweest, ook is het handig om te weten aangezien dit zeer zeker niet mijn laatste site zal zijn die ik maak :)

@sloth: bedankt! ik ga er eventjes naar kijken...


@iedereen, bedankt voor de reactie's tot nu toe!

Acties:
  • 0 Henk 'm!

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

Maaark schreef op donderdag 27 januari 2011 @ 20:48:
- Is het gebruiken van een sleep() bij het inloggen noodzakelijk? Aangezien het liefst alles natuurlijk zo snel mogelijk moet gaan?
Tja, waarom zou je onnodig vertragen? Dat werkt alleen maar avrechts op "de werking" en de userexperience van de site an sich.
- Hoeveel mislukte inlog pogingen zijn normaal voordat er een tijdelijk ban word uitgedeeld?
Sterk afhankelijk van de doelgroep, maar 3x het meest gebruikte, zoiets blijft gewoon puur voorkeur, maak er eventueel een instelling van, zodat je het later makkelijk(er) kan aanpassen.
- Opslaan van wachtwoorden:
Hoe kan dit het veiligste? Nu gebruik ik altijd nog gewoon md5 ervoor, maar is het handig om bijvoorbeeld de md5 waarde te pakken en dan per user een aantal unieke tekens achter elkaar te zetten en die aan de md5 plakken en daar een sha1 van te maken?
"Het beste" of "het veiligste" is er natuurlijk natuurlijk niet. Versleuteling wordt namelijk steeds maar beter en beter. Nu is SHA512 redelijk standaard, en over 5 jaar is dat misschien wel SHA4096 (ik zeg even iets). Gebruik wel een (random gegenereerde) 'salt', zoals eerder genoemd, daarmee voeg je een soort van troebel toe. ;)
- Opslaan van email adressen:
Is het verstandig om de email adressen te coderen via een encryption key? En dan het email adres bij registratie te versleutelen met deze key en als het email adres nodig is deze te dectypten?
En waar moet de decryptionkey opgeslagen worden dan? ;) MAW: IMO schiet je daar zoveel niet mee op. Alleen als iemand in de database zit, maar meestal komen inbrekers toch wel verder... ;)
- Mis ik nog beveiligingsfunctie’s die echt niet mogen ontbreken?
Je zou eens kunnen kijken naar SSL.
ReenL schreef op donderdag 27 januari 2011 @ 21:06:
"Mis ik nog beveiligingsfunctie’s die echt niet mogen ontbreken?"
De db abstractie laag :). Plus ik ben benieuwd wat er in de database staat wat het zo veilig moet maken. Credit card gegevens? Want dan kan ik nog wel een uurtje doorgaan ;)
Een DataBase Abstraction Layer (DBAL) is niet per sé nodig als je het mij vraagt, je moet er teveel resources voor inleveren, als je gewoon rekening houdt met bijvoorbeeld SQL-injection, dan is de kans erop al vele malen kleiner.

[ Voor 16% gewijzigd door CH4OS op 27-01-2011 21:41 ]


Acties:
  • 0 Henk 'm!

  • dev10
  • Registratie: April 2005
  • Laatst online: 09:00
Maaark schreef op donderdag 27 januari 2011 @ 20:48:
- Is het gebruiken van een sleep() bij het inloggen noodzakelijk? Aangezien het liefst alles natuurlijk zo snel mogelijk moet gaan?
Nee, ik vind het onwenselijk dat ik bij het inloggen een x aantal seconden moet wachten.
- Opslaan van email adressen:
Is het verstandig om de email adressen te coderen via een encryption key? En dan het email adres bij registratie te versleutelen met deze key en als het email adres nodig is deze te dectypten?
In principe is het niet nodig om een emailadres versleuteld in de database op te slaan. Je moet er alleen voor zorgen dat je emailadressen niet zomaar op je website weergeeft.
- Mis ik nog beveiligingsfunctie’s die echt niet mogen ontbreken?
Zoals hierboven al vermeld is, is het handig om te kijken naar SSL. Verder al de input escapen voor je ermee aan de gang gaat in je query's. (mysql_real_escape_string()) En verder ook data die je weergeeft escapen met htmlspecialchars(). Met de laatste twee punten vang je SQL-Injection en XSS af.

Acties:
  • 0 Henk 'm!

  • Maaark
  • Registratie: Juli 2008
  • Laatst online: 02-06 11:35
CptChaos schreef op donderdag 27 januari 2011 @ 21:25:
[...]
Tja, waarom zou je onnodig vertragen? Dat werkt alleen maar avrechts op "de werking" en de userexperience van de site an sich.
[...]
Sterk afhankelijk van de doelgroep, maar 3x het meest gebruikte, zoiets blijft gewoon puur voorkeur, maak er eventueel een instelling van, zodat je het later makkelijk(er) kan aanpassen.
[...]
"Het beste" is er natuurlijk natuurlijk niet. Versleuteling wordt namelijk steeds maar beter en beter. Nu is SHA512 redelijk standaard, en over 5 jaar is dat misschien wel SHA4096 (ik zeg even iets). Gebruik wel een (random gegenereerde) 'salt', zoals eerder genoemd, daarmee voeg je een soort van troebel toe. ;)
[...]
En waar moet de decryptionkey opgeslagen worden dan? ;) MAW: IMO schiet je daar zoveel niet mee op. Alleen als iemand in de database zit, maar meestal komen inbrekers toch wel verder... ;)
[...]
Je zou eens kunnen kijken naar SSL.
SSL staat al op het lijstje ;) Het zijn alleen punten in dit topic waar ik nog aan twijfel.
Als ik een random gegenereerde salt wil gaan gebruiken, waar moet ik die random waarde dan opslaan? Ook in de database? Anders kan ik hem toch niet uniek houden voor elke gebruiker? Of hoeft die niet uniek te zijn voor elke gebruiker maar moet het gewoon een willekeurige reeks zijn?

Ik zie dat het opslaan van sha512 geen probleem moet geven, maar als ik meer wil dan 512 word het dus wel een probleem, zie http://www.php.net/manual/en/function.hash-algos.php of mag ik aannemen dat er nog aan gewerkt gaat worden?

Over het vertragen, ik denk dat niemand de site als minder prettig aanvaart als er een vertraging van 1 seconde in zit, denk dat dat wel geaccepteerd word?

SQL injecten en XSS worden naar mijn mening al goed opgevangen, ik gebruik codeigniter en daar word standaard al veel opgevangen (alleen XSS niet standaard).

[ Voor 4% gewijzigd door Maaark op 27-01-2011 21:35 ]


Acties:
  • 0 Henk 'm!

Anoniem: 289377

Neem een salt van 120 tekens en plak deze achter het wachtwoord. Anders kun je namelijk de eerste blocks berekenen bij een brutefoce aanval. Doe verder een salt per username, deze sla je gewoon op in een extra kolom in de database. Zo moet een hacker elke user apart gaan bruteforcen. Als laatste is het belangrijk om te gaan stretchen. Omdat men tegenwoordig bruteforced met een videokaart ipv cpu is het belangrijk om het proces zoveel mogelijk te vertragen. Een videokaart kan namelijk veel sneller hashes bereken dan een cpu (1.2 miljard per seconde is geen gek getal). Oja en MD5 is echt wel veroudert, pak liever SHA512.

Stukje voorbeeld code:

code:
1
2
3
4
5
hash = sha512(password + salt);

for (int i = 0; i < 1000; i++) {
    hash = sha512(hash);
}

Acties:
  • 0 Henk 'm!

  • Aganim
  • Registratie: Oktober 2006
  • Laatst online: 09:35

Aganim

I have a cunning plan..

Ik wil bij de inlogpogingen liever het ip adres blokkeren, als ik tijdelijk een account blokkeer ben ik bang dat ik straks een site heb waar niemand meer kan inloggen..
Maar is dat wenselijk? Niets irritanters als een wisselend IP adres hebben, op een site komen en niet kunnen inloggen, omdat iemand anders zich misdragen heeft met het adres dat je momenteel is toegewezen.

Acties:
  • 0 Henk 'm!

  • sloth
  • Registratie: Januari 2010
  • Niet online
Wat je zegt klopt wel in theorie...maar in werkelijkheid?

De ts heeft geen bezoekersaantallen genoemd, maar ik ga uit van een site die geen 1000'en unieke bezoekers per dag heeft.

De kans dat je dan net 2 users hebt, die bij dezelfde isp zitten, waarvan de 1 z'n ip gebanned wordt en de andere dan net dat ip ontvangt lijkt me bijzonder klein.

Acties:
  • 0 Henk 'm!

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

Maaark schreef op donderdag 27 januari 2011 @ 21:34:
Als ik een random gegenereerde salt wil gaan gebruiken, waar moet ik die random waarde dan opslaan? Ook in de database? Anders kan ik hem toch niet uniek houden voor elke gebruiker? Of hoeft die niet uniek te zijn voor elke gebruiker maar moet het gewoon een willekeurige reeks zijn?
Een random gegenereerde salt is een eigenschap van elk gebruikersaccount, dus ja, die komt dan ook in de database te staan inderdaad, in de tabel met users. Als je MySQL gebruikt, kan dat gewoon een tinytext zijn (is 255 tekens maximaal). Je wachtwoord is dan dus een versleuteling (MD5, SHA e.d.) van het gebruikerswachtwoord + de salt.
Ik zie dat het opslaan van sha512 geen probleem moet geven, maar als ik meer wil dan 512 word het dus wel een probleem, zie http://www.php.net/manual/en/function.hash-algos.php of mag ik aannemen dat er nog aan gewerkt gaat worden?
Dat is, al hoopte ik dat het in jou zou opkomen, een zorg voor later. SHA512 is momenteel sterk genoeg.
code:
1
2
3
for (int i = 0; i < 1000; i++) {
    hash = sha512(hash);
}
Is een vertraging van lik-m'n-vestje, hier is een beetje webserver in een mum van tijd doorheen, loze code voor ook de webserver zelf.

[ Voor 13% gewijzigd door CH4OS op 27-01-2011 21:49 ]


Acties:
  • 0 Henk 'm!

  • Maaark
  • Registratie: Juli 2008
  • Laatst online: 02-06 11:35
@Kamose thanks, dat zal het inderdaad een heel stuk moeilijker maken :)

@Aganim&Sloth, het is inderdaad wel iets om rekening mee te houden, maar het lijkt mij op dit moment nog onnodig. Op een oudere versie van de site kwamen ongeveer 250 unieke bezoekers per dag dus de kans dat ze het zelfde ipadres toegewezen krijgen EN dat er 1 van hun stout is geweest is dan wel erg klein.

@CptChaos, dat maakte ik er ookal uit op :) het was meer iets van vooruit denken :)

[ Voor 10% gewijzigd door Maaark op 27-01-2011 21:49 ]


Acties:
  • 0 Henk 'm!

  • ReenL
  • Registratie: Augustus 2010
  • Laatst online: 14-09-2022
"Ik wil bij de inlogpogingen liever het ip adres blokkeren,"
Een hacker kan een hele zwik aan ip-addressen hebben tuurlijk kan een ip ban geen kwaad maar dat zegt niet dat de hacker gestopt is. Met een account block vertraag je een hacker wel.

"Ik bedoel geen cookie's, $_SESSION[waarde] gebruik ik, ik gebruik session id omdat het zo handig is om query's te doen"
Hoe ziet dat er in code uit. Het klinkt namelijk alsof het niet werkt hoe jij verwacht.

"zit die daar standaard in"
Ja, maar dan moet je 'm wel gebruiken. Dus ipv: "SELECT * FROM a WHERE id = ".((int)$id); gebruik je iets als:

PHP:
1
2
3
$q->select('*')
    ->from('a')
    ->where('id = ?', $id);


"Ik ga niet echt belangrijke data opslaan"
Vergeet niet de salt per gebruiker te doen en niet per applicatie ;)
edit:
Ja de salt mag ook in de DB :)


"Een DataBase Abstraction Layer (DBAL) is niet per sé nodig"
Dat klopt, maar wat je aan performance inlevert krijg je aan veiligheid 3x terug, omdat de kans op fouten een stuk kleiner is.

Acties:
  • 0 Henk 'm!

  • Maaark
  • Registratie: Juli 2008
  • Laatst online: 02-06 11:35
ReenL schreef op donderdag 27 januari 2011 @ 21:48:
"Ik wil bij de inlogpogingen liever het ip adres blokkeren,"
Een hacker kan een hele zwik aan ip-addressen hebben tuurlijk kan een ip ban geen kwaad maar dat zegt niet dat de hacker gestopt is. Met een account block vertraag je een hacker wel.

"Ik bedoel geen cookie's, $_SESSION[waarde] gebruik ik, ik gebruik session id omdat het zo handig is om query's te doen"
Hoe ziet dat er in code uit. Het klinkt namelijk alsof het niet werkt hoe jij verwacht.

"zit die daar standaard in"
Ja, maar dan moet je 'm wel gebruiken. Dus ipv: "SELECT * FROM a WHERE id = ".((int)$id); gebruik je iets als:

PHP:
1
2
3
$q->select('*')
    ->from('a')
    ->where('id = ?', $id);


"Ik ga niet echt belangrijke data opslaan"
Vergeet niet de salt per gebruiker te doen en niet per applicatie ;)

"Een DataBase Abstraction Layer (DBAL) is niet per sé nodig"
Dat klopt, maar wat je aan performance inlevert krijg je aan veiligheid 3x terug, omdat de kans op fouten een stuk kleiner is.
toon volledige bericht
Wat je zegt over vele ipadressen die een hacker tot zijn beschikking heeft en dat het tijdelijk blokkeren van een account vertraging oplevert klopt ook weer inderdaad.. Is dus echt iets waar nog eventjes over nagedacht moet worden.

Wat ik doe met de session:
Bij inloggen gewoon de session id maken en dan als ik iets wil doen:
code:
1
$select = mysql_query("SELECT waarde FROM users WHERE id = '".$_SESSION["id"]."'");
bijvoorbeeld :)

Thanks voor je voorbeeld nog :) Wist ik niet.

Acties:
  • 0 Henk 'm!

  • ReenL
  • Registratie: Augustus 2010
  • Laatst online: 14-09-2022
Met je code voorbeeld is het nog steeds niet duidelijk hoe je die check precies doet.

Waar je op moet letten:
session_id() <<= random, staat in $_COOKIE['PHPSESSID']; (of iets in die richting).

De interne php code ziet er zoiets uit:
code:
1
$_SESSION = unserialize(file_get_contents('/path/to/tmp/phpsession-'.session_id()));


De session_id bepaald dus wat er in $_SESSION staat. Als de session_id gestolen wordt. Is de inhoud van $_SESSION ook volledig overgenomen en daarbij lijkt je check overbodig.

Acties:
  • 0 Henk 'm!

  • Maaark
  • Registratie: Juli 2008
  • Laatst online: 02-06 11:35
ReenL schreef op donderdag 27 januari 2011 @ 22:01:
Met je code voorbeeld is het nog steeds niet duidelijk hoe je die check precies doet.

Waar je op moet letten:
session_id() <<= random, staat in $_COOKIE['PHPSESSID']; (of iets in die richting).

De interne php code ziet er zoiets uit:
code:
1
$_SESSION = unserialize(file_get_contents('/path/to/tmp/phpsession-'.session_id()));


De session_id bepaald dus wat er in $_SESSION staat. Als de session_id gestolen wordt. Is de inhoud van $_SESSION ook volledig overgenomen en daarbij lijkt je check overbodig.
Hmm dat wist ik niet :) Hoe kan ik dit dan voorkomen?

Acties:
  • 0 Henk 'm!

  • ReenL
  • Registratie: Augustus 2010
  • Laatst online: 14-09-2022
Opzich is de session_id generator redelijk te vertrouwen (hoewel op defcon wel een reeks zwaktes gedemonstreerd is). Wat je kunt doen:
PHP:
1
2
3
4
5
6
7
<?php
session_start();
if ( !isset($_SESSION['check']) || $_SESSION['check'] != $_COOKIE['check'] ) {
    $_SESSION = array();
    $_SESSION['check'] = generateRandomString();
    setcookie('check', $_SESSION['check']);
}


Daar een string van 20 tekens ofzo, mt_rand() en niet rand() gebruiken.

Ps: Omdat je de check ook in de cookies opslaat kan iemand die de sessie cookie gestolen heeft ook makkelijk de check stelen. Dit is om de session_id randomness te vergroten.

[ Voor 21% gewijzigd door ReenL op 27-01-2011 22:12 . Reden: Foutje in code :) ]


Acties:
  • 0 Henk 'm!

  • Maaark
  • Registratie: Juli 2008
  • Laatst online: 02-06 11:35
ReenL schreef op donderdag 27 januari 2011 @ 22:10:
Opzich is de session_id generator redelijk te vertrouwen (hoewel op defcon wel een reeks zwaktes gedemonstreerd is). Wat je kunt doen:
PHP:
1
2
3
4
5
6
7
<?php
session_start();
if ( !isset($_SESSION['check']) || $_SESSION['check'] != $_COOKIE['check'] ) {
    $_SESSION = array();
    $_SESSION['check'] = generateRandomString();
    setcookie('check', $_SESSION['check']);
}


Daar een string van 20 tekens ofzo, mt_rand() en niet rand() gebruiken.

Ps: Omdat je de check ook in de cookies opslaat kan iemand die de sessie cookie gestolen heeft ook makkelijk de check stelen. Dit is om de session_id randomness te vergroten.
toon volledige bericht
Dankje, mag ik nu wel of niet iets gebruiken als
code:
1
mysql_query("UPDATE users SET waarde = '".$waarde."' WHERE id = '".$_SESSION["userid"]."');


Als ik bij elke page request check of degene wel de juiste sessions heeft?

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Maaark schreef op donderdag 27 januari 2011 @ 20:48:
- Is het gebruiken van een sleep() bij het inloggen noodzakelijk? Aangezien het liefst alles natuurlijk zo snel mogelijk moet gaan?
Wat is hier het nut van? Je laat je server een thread vasthouden en de gebruiker drukt op F5 en pakt een tweede thread? Eigenlijk zie ik er geen enkel voordeel in en enkel een grote kans om je eigen site te DOSSEN.

Wat je gewoon moet doen is bij begin inlogpoging ip/account opslaan in tabel daarvoor in diezelfde tabel kijken of ip of account er al instaat met een tijd korter dan x sec. Zoja, deny login ook al is het wachtwoord goed. Zonee, log gebruiker in en zet in de inlogpogingen tabel een vlaggetje om zodat hij niet geblokkeerd is.

Door het altijd op te slaan met tijd erbij kan je ook veel flexibeler regels maken ( bijv 1e 3x in 1 uur is 1 sec vertraging, daarboven ga je voor 5 sec vertraging en bij meer dan 20 per uur ( of 200 per dag ) gooi je er een vertraging van een half uur op ) op deze manier hoef je ook niet meer elke user te vertragen.

Doordat je effectief steeds verder de inlogpogingen compleet gaat blokkeren ( en altijd dezelfde error blijft geven ) is het niet interessant meer of een script weet dat hij geblokkeerd wordt, hij weet enkel dat hij nog geblockt wordt, niet of het wachtwoord wat hij net probeerde juist was.

Ander leuk geintje wat ik wel eens tegengekomen ben bij het inloggen was iemand die wel enigszins een terugmelding gaf waarom de inlog gefaald was. Enkel verpakte hij de tekst in een captcha plaatje, waardoor de scriptkiddie echt een captcha ding ervoor moesten bouwen als ze de melding wilden hebben.
Maaark schreef op donderdag 27 januari 2011 @ 21:18:
@beany: Dat is inderdaad een goed plan :) Alleen heb ik zelf ook wel eens dat ik 10x moet raden welk wachtwoord ik gebruik... dan zou deze sleep tijd een beetje erg onvriendelijk zijn?
Die vertragings taktieken moet je ook niet echt merkbaar maken bij 10 pogingen ( gewoon erg kort houden ), 10 pogingen kan nog een mens zijn. 20 pogingen is zeer waarschijnlijk al geen mens meer. 50 pogingen is zo goed als zeker geen mens meer.
[...]
Ik wil bij de inlogpogingen liever het ip adres blokkeren, als ik tijdelijk een account blokkeer ben ik bang dat ik straks een site heb waar niemand meer kan inloggen..
Gewoon ip blokkeren en gelijk account blokkeren als het boven bepaalde grenswaardes gaat ( die waardes hoeven niet gelijk te zijn bij ip en account ) een "hacker" kan gewoon via proxy-servers en tor etc werken waardoor ip waardeloos is.
Ik bedoel geen cookie's, $_SESSION[waarde] gebruik ik, ik gebruik session id omdat het zo handig is om query's te doen :)
Dus eigenlijk verstuur jij de sessionkey altijd in de url? Want normale implementatie gaat via cookies...
Over de email adressen: mooi, dan kan ik dat achterwegen laten, scheelt weer :)
Afhankelijk van de tabel ( enkel email adressen vind ik vrij nutteloos, complete naw tabel vind ik wel weer nuttig ) kan het toch wel een overweging zijn om toch een encryptie met een sleutel buiten www-root (/server) te hebben.
Niet versleutelen betekent dat iemand maar een sql-statement hoeft te kunnen misbruiken om die tabel leeg te halen. Wel versleutelen betekent en sql-toegang en buiten www-root toegang wat de hacker allebei nodig heeft. Het is gewoon een extra laagje.
- Opslaan van wachtwoorden:
Hoe kan dit het veiligste? Nu gebruik ik altijd nog gewoon md5 ervoor, maar is het handig om bijvoorbeeld de md5 waarde te pakken en dan per user een aantal unieke tekens achter elkaar te zetten en die aan de md5 plakken en daar een sha1 van te maken?
Plain md5 is ongeveer hetzelfde als gewoon plain opslaan. Er zwerven genoeg plain md5 rainbowtables rond.
- Mis ik nog beveiligingsfunctie’s die echt niet mogen ontbreken?
Hangt af van de data die je gaat opslaan. Voor een simpel blogje is het meer dan genoeg, voor een webshop met betaalgegevens zou ik iets meer toepassen.

Acties:
  • 0 Henk 'm!

  • Bv202
  • Registratie: Oktober 2006
  • Laatst online: 14-11-2021
Wat ik even niet snap hier is wat het nut precies is van de sleep()-functie te gebruiken bij het inloggen. Wat draagt dit bij aan de veiligheid?

Acties:
  • 0 Henk 'm!

  • Maaark
  • Registratie: Juli 2008
  • Laatst online: 02-06 11:35
Bedankt :) Het maakt het maken van een keuze over de sleep() functie is zo wat makkelijk geworden, ik denk dat ik voor een systeempje ga zoals jij omschrijft.

Daarnaast zeg je "gewoon blokkeren", is dit dan tijdelijk of?

Naar mijn weten verstuur ik geen sessionkeys in de url...

[ Voor 77% gewijzigd door MueR op 27-01-2011 22:40 ]


Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 09:49

MueR

Admin Tweakers Discord

is niet lief

Maaark: wanneer je 100 regels quote om er vier onder te plaatsen, leest dat vrij vervelend voor de rest. Knip liever de inhoud van de quote weg.

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • Maaark
  • Registratie: Juli 2008
  • Laatst online: 02-06 11:35
Sorry, zal er rekening mee houden.

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Maaark schreef op donderdag 27 januari 2011 @ 22:34:
[...]
Daarnaast zeg je "gewoon blokkeren", is dit dan tijdelijk of?
Blokkeren is bij mij altijd tijdelijk. Maar max date_timevalue komt meestal effectief neer op complete blokkade.
Ik blokkeer dus altijd gewoon tot een eindtijd + einddatum. Dan heb je de flexibiliteit om 1 seconde te blokkeren ( tijdens inloggen ) maar ook in hetzelfde veldje te blokkeren tot max values ( categorie, zie ik in 2039 wel weer ).

Dan kan je met 1 of 2 dbase-velden de meeste banvormen gewoon invullen .ok praktisch zijn het er iets meer geworden, maar dat is allemaal verfraaiing / caching etc. basis is ip-blocks in tabel 1 ( zodat als langer dan half uur die in de firewall gezet kan worden ( cronjob om het uit de firewall te halen draait maar 1x per half uur )) en account-blocks gewoon in de user-properties tabel ( zodat admins het ook overzichtelijk in hun overzichten kunnen zien )
Naar mijn weten verstuur ik geen sessionkeys in de url...
Dan gebruik je dus toch gewoon cookies om je sessionkey in te bewaren. Dus cookies, die zou ik persoonlijk dan nog op bepaalde factoren ( ip-adres / browser etc ) locken want die zijn gewoon te kopieren van computer naar computer (zoek voor de grap eens in je favoriete p2p programma naar temporary inet files of cookies)

offtopic:
@Muer : maar het zag eruit als een heel intelligente post, ik vond hem ook de moeite van het quoten waard :)

[ Voor 4% gewijzigd door Gomez12 op 27-01-2011 23:00 ]


Acties:
  • 0 Henk 'm!

  • Maaark
  • Registratie: Juli 2008
  • Laatst online: 02-06 11:35
Dat verhaal van de cookie's wist ik niet, wat leer ik toch veel vanavond :)

Het is mij nu duidelijk dankje. Alleen begin ik mij nu toch af te vragen voor welke site je een dergelijk systeem gemaakt hebt, lijkt mij niet de kleinste :) Als je het niet op het forum wilt zetten kun je het eventueel ook naar mij sturen als PM.

Thanks iedereen!

Nog 1 laatste vraag over SSL:

Ik zie vaak bij site’s dat je vanaf de eerste pagina van de site kunt inloggen, vaak zijn het ook nog best belangrijke site’s zoals mollie en pay.nl. Deze pagina is bij hun niet beveiligd via SSL maar vanaf de login page is bij hun dan wel alles beveiligd. Nu vraag ik mij af, aangezien je de informatie vanaf een onbeveiligde pagina verstuurd naar een beveiligde pagina, is dit wel veilig?


offtopic:
De inhoud van de quote was inderdaad wel de moeite waard haha

[ Voor 44% gewijzigd door Maaark op 27-01-2011 23:12 . Reden: SSL vraag erbij ]


Acties:
  • 0 Henk 'm!

  • LinuX-TUX
  • Registratie: December 2003
  • Laatst online: 29-04 11:02
Maaark schreef op donderdag 27 januari 2011 @ 20:48:
Hallo Tweakers,
[..]

- Mis ik nog beveiligingsfunctie’s die echt niet mogen ontbreken?

Alvast bedankt
Een must have waar je nog niet op gelet had: geparameteriseerde queries. ALTIJD. (prepared statements, genoeg om in te verdiepen om 'onveiligheden' tegen te gaan)

http://www.google.com/sea...&aql=&oq=php+mysql+parame

http://dev.mysql.com/tech...uide-to-php-security.html

Waarom?
SQL injection :Y)

[ Voor 17% gewijzigd door LinuX-TUX op 27-01-2011 23:29 ]


Acties:
  • 0 Henk 'm!

  • Maaark
  • Registratie: Juli 2008
  • Laatst online: 02-06 11:35
Is dat niet wat ReenL als voorbeeld gepost heeft?

Acties:
  • 0 Henk 'm!

  • joppybt
  • Registratie: December 2002
  • Laatst online: 02-06 22:30
Aganim schreef op donderdag 27 januari 2011 @ 21:39:
[...]

Maar is dat wenselijk? Niets irritanters als een wisselend IP adres hebben, op een site komen en niet kunnen inloggen, omdat iemand anders zich misdragen heeft met het adres dat je momenteel is toegewezen.
Of erger nog: iemand zit op school en gaat door een proxy naar de buitenwereld. Alle scholieren komen dan met hetzelfde IP-adres op jouw site terecht. Als één iemand zich misdragen heeft moet je niet zo maar de rest uitsluiten.
Dat heeft verder niets met wisselende ip-adressen te maken.

Acties:
  • 0 Henk 'm!

  • Barleone
  • Registratie: Maart 2009
  • Laatst online: 06:15
joppybt schreef op donderdag 27 januari 2011 @ 23:43:
[...]

Of erger nog: iemand zit op school en gaat door een proxy naar de buitenwereld. Alle scholieren komen dan met hetzelfde IP-adres op jouw site terecht. Als één iemand zich misdragen heeft moet je niet zo maar de rest uitsluiten.
Dat heeft verder niets met wisselende ip-adressen te maken.
Klinkt misschien gek, maar dat zou je kunnen achterhalen door statistieken te maken, zodat je kan zien: vanaf IP-adres x.x.x.x. wordt regelmatig ingelogd op diverse accounts. Het zou in dat geval niet slim zijn om dat IP-adres te blokkeren. Je 'weet' dan namelijk dat je meteen een heleboel gebruikers afsluit.
Disclaimer: dit verzin ik hier ter plekke.

Tweakers.net 6 nostalgie! - Wayback Machine
Have you tried turning it off and on again?


Acties:
  • 0 Henk 'm!

  • Patriot
  • Registratie: December 2004
  • Laatst online: 00:24

Patriot

Fulltime #whatpulsert

Maaark schreef op donderdag 27 januari 2011 @ 23:41:
Is dat niet wat ReenL als voorbeeld gepost heeft?
Min of meer. Parameterized queries kunnen ook zonder een database abstraction layer, maar een database abstraction layer maakt meestal wel gebruik van parameterized queries (voor zover dat van toepassing is).

Acties:
  • 0 Henk 'm!

  • LinuX-TUX
  • Registratie: December 2003
  • Laatst online: 29-04 11:02
Maaark schreef op donderdag 27 januari 2011 @ 23:41:
Is dat niet wat ReenL als voorbeeld gepost heeft?
Sjees, sorry, over heen gelezen. Had een snelle Ctrl+F op "param" gedaan in dit topic. DB abstractie laag is nagenoeg hetzelfde ja. Mijn tip is direct op PHP taal gebaseerd, abstractie laag forceerd je nagenoeg dit te doen.

Acties:
  • 0 Henk 'm!

  • Maaark
  • Registratie: Juli 2008
  • Laatst online: 02-06 11:35
LinuX-TUX schreef op vrijdag 28 januari 2011 @ 00:04:
[...]

Sjees, sorry, over heen gelezen. Had een snelle Ctrl+F op "param" gedaan in dit topic. DB abstractie laag is nagenoeg hetzelfde ja. Mijn tip is direct op PHP taal gebaseerd, abstractie laag forceerd je nagenoeg dit te doen.
Thanks :) Dacht al dat ik nog iets nieuws moest gaan bekijken :)

Maar nu is het wel bedtijd :) Vandaag veel geleerd :)

Acties:
  • 0 Henk 'm!

  • Nijn
  • Registratie: Januari 2005
  • Laatst online: 08:13
CptChaos schreef op donderdag 27 januari 2011 @ 21:44:
[...]
Een random gegenereerde salt is een eigenschap van elk gebruikersaccount, dus ja, die komt dan ook in de database te staan inderdaad, in de tabel met users. Als je MySQL gebruikt, kan dat gewoon een tinytext zijn (is 255 tekens maximaal). Je wachtwoord is dan dus een versleuteling (MD5, SHA e.d.) van het gebruikerswachtwoord + de salt.
[...]
Dat is, al hoopte ik dat het in jou zou opkomen, een zorg voor later. SHA512 is momenteel sterk genoeg.
code:
1
2
3
for (int i = 0; i < 1000; i++) {
    hash = sha512(hash);
}
Is een vertraging van lik-m'n-vestje, hier is een beetje webserver in een mum van tijd doorheen, loze code voor ook de webserver zelf.
Ik haal even een wat oudere post terug, omdat het best belangrijk is.

Zoals Kamose al zegt: tegenwoordig brute-force je met een processor die op parallelle wijze berekeningen uitvoert. Een GPU kan honderden berekeningen per clock cycle uitvoeren. Sinds de komst van GPU Computing niet alleen salting maar ook stretching vrij belangrijk geworden. (Zeker over een paar jaar!)

Wat je met stretching doet is simpel. Zonder stretching zou je een string 1x door het SHA algoritme halen. GPU X zou dan zeg 1 miljard pogingen per seconden kunnen doen om erachter te komen wat het wachtwoord is.

Met stretching haal je een string bijvoorbeeld 1000x door het SHA algoritme. Inderdaad, de voor een webserver is dat niks. Maar, als je het miljarden keren moet doen (brute-forcen) wordt het heel wat. Het brute-forcen van een wachtwoord wordt hierdoor simpelweg 1000x trager. Opeens kan GPU X nog maar 1 miljoen pogingen per seconden doen.

Met de volgende code maak je het opslaan van de wachtwoorden dus een stuk veiliger:
code:
1
2
3
4
5
hash = sha512(password + salt);

for (int i = 0; i < 1000; i++) {
    hash = sha512(hash);
}


Wil je het echt perfect doen, dan voeg je daar nog een kleinigheidje aan toe. Een variable iteration count. In plaats van de string altijd 1000x door het algoritme te halen, doe je het 1000+X keer. (waar X ergens tussen 1 en 1000 ligt bijvoorbeeld). Het beste is om X apart te genereren en op te slaan, maar je kunt ook een redelijk random X genereren met de waarde van "hash" (zie code) voor het begin van de for loop.

Knappe jongen die het dan nog lukt om de wachtwoorden te achterhalen.

Acties:
  • 0 Henk 'm!

  • trinite_t
  • Registratie: Maart 2003
  • Laatst online: 28-05 15:03
Volgens mij ga je hierdoor juist de kans op collisions vergroten en wil je dit juist niet.

The easiest way to solve a problem is just to solve it.


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Jep, als de aanvaller enkel online kan proberen is elke willekeurige andere manier van tijdrekken net zo effectief, maar dan zonder dat je het aantal mogelijke hashes kleiner maakt. :z

{signature}


Acties:
  • 0 Henk 'm!

  • PeterSelie
  • Registratie: December 2002
  • Laatst online: 19-05 11:09
trinite_t schreef op vrijdag 28 januari 2011 @ 10:04:
Volgens mij ga je hierdoor juist de kans op collisions vergroten en wil je dit juist niet.
Verkeerd gelezen.. :O

[ Voor 42% gewijzigd door PeterSelie op 28-01-2011 10:13 ]


Acties:
  • 0 Henk 'm!

  • dev10
  • Registratie: April 2005
  • Laatst online: 09:00
Maaark schreef op donderdag 27 januari 2011 @ 21:34:
[...]

Over het vertragen, ik denk dat niemand de site als minder prettig aanvaart als er een vertraging van 1 seconde in zit, denk dat dat wel geaccepteerd word?
Ik wel.

Ik zou een vertraging ook niet doen door middel van sleep(), omdat het dan lijkt alsof de pagina 'hangt'.

Acties:
  • 0 Henk 'm!

  • trinite_t
  • Registratie: Maart 2003
  • Laatst online: 28-05 15:03
Nu ik er even over nadenk lijkt het me zelfs makkelijker om een passend wachtwoord te achterhalen, aangezien je het aantal verschillende (plain text) wachtwoord mogelijkheden juist beperkt. Dit zorgt er voor dat je veel sneller een rainbow table kunt opbouwen.

Wat je dan denk ik moet doen is een standaard rainbow table van passwd->hash pakken (of zelf bouwen),
en dan zelf een rainbow table opbouwen waarin je elke beschikbare hash nog 999 keer hashed (het aantal mogelijke hashes is "redelijk" beperkt., alleen de bereken tijd per hash duurt nogal lang, maar daar hebben we gpu's voor).
edit:
Idd, maar een hash is nodig, zie hieronder


Combineer die tabellen en je hebt het wachtwoord.


Wat ik me verder nog afvroeg, ik heb ooit als een "poor mans" solution een login systeem geschreven die elke keer dat je inlogt een random seed verstuurd, en hiermee het password met javascript hashed met de volgende methode:
code:
1
hash(seed + hash(passwd));
De salt stuur je mee met de website waarop het login formulier staat. Bij het submitten van het formulier stuur je deze bewust niet mee.

Dit kun je dan bij je checkpassword functie ook doen waardoor je het wachtwoord versleuteld kunt versturen. Je loopt er hierbij alleen tegen aan dat je volgens mij het wachtwoord in je database wel gehashed kunt opslaan, maar niet kunt hashen met een salt. Zouden jullie dan voor deze methode kiezen of toch deze methode overslaan en de hash in de database salten.

The easiest way to solve a problem is just to solve it.


Acties:
  • 0 Henk 'm!

  • ReenL
  • Registratie: Augustus 2010
  • Laatst online: 14-09-2022
Maaark schreef op donderdag 27 januari 2011 @ 22:17:
[...]


Dankje, mag ik nu wel of niet iets gebruiken als
code:
1
mysql_query("UPDATE users SET waarde = '".$waarde."' WHERE id = '".$_SESSION["userid"]."');


Als ik bij elke page request check of degene wel de juiste sessions heeft?
Nee, Waar komt $waarde vandaan? Hoe heb je SQL-Injection voorkomen? En de voorkeur is om geen raw-sql te schrijven.

Als het nog steeds om sessie beveiliging gaat:
Waarmee vergelijk je $waarde, voor je check? Als dat met iets in de sessie is, stel je, je server alleen een vraag waar die altijd ja op zegt.

Als je $waarde met een cookie vergelijkt, dan heb je een query gedaan die niet nodig was. En die check is er alleen maar om je session_id minder voorspelbaar te maken. Als je geen "wie kwam wanneer online" systeem hebt, hoef je, jezelf in principe niet druk te maken. Daarnaast is zonder SSL het cookie makkelijk te achterhalen.

"Ik zie vaak bij site’s dat je vanaf de eerste pagina van de site kunt inloggen"
Als je SSL gebruikt, gebruik het dan overal en maak je cookies ssl-only. In sommige systemen zou je op sommige pagina's theoretisch ook zonder kunnen. Maar totdat je precies weet waar je mee bezig bent, zou ik me eerst verdiepen in alle andere stof.

100 of 1000 keer hashen heeft geen zin. Waarom niet?

stel ik doe dit:
sha512($password . $salt);
Dan is de uitkomst daarvan een string(128) (pin me er niet aan vast)

Als je vervolgens een rainbow table hebt/maakt met alle sha512 strings en daar een sha512 overheen doet. Dan kun je hem binnen no-time terugrekenen naar die eerste string(128), onafhankelijk van hoe vaak je de shaX functie uitvoert, dan ben je weer terug bij af.

Als je voor elke iteratie een unieke salt had per gebruiker werkt het misschien.

Teveel mogelijkheden met sha512 om het rendabel te maken.

[ Voor 19% gewijzigd door ReenL op 28-01-2011 22:43 ]


Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Nijn schreef op vrijdag 28 januari 2011 @ 00:40:
[...]
Met de volgende code maak je het opslaan van de wachtwoorden dus een stuk veiliger:
code:
1
2
3
4
5
hash = sha512(password + salt);

for (int i = 0; i < 1000; i++) {
    hash = sha512(hash);
}

...
Knappe jongen die het dan nog lukt om de wachtwoorden te achterhalen.
Wachtwoorden achterhalen maak je in wezen al met een md5 en geschikte lengte/compexiteit van wachtwoord onmogelijk (als jouw 20-cijferige ww een collision heeft met de letter b dan gaan de meeste rainbow tables enkel de b als antwoord produceren, meer heb je ook niet nodig om binnen te komen).

1000x hashen vergroot enkel de kans op een collision, alhoewel het wachtwoord moeilijker te achterhalen wordt, wordt het binnenkomen enkel maar makkelijker...

Acties:
  • 0 Henk 'm!

Anoniem: 289377

Gomez12 schreef op vrijdag 28 januari 2011 @ 20:45:
[...]

Wachtwoorden achterhalen maak je in wezen al met een md5 en geschikte lengte/compexiteit van wachtwoord onmogelijk (als jouw 20-cijferige ww een collision heeft met de letter b dan gaan de meeste rainbow tables enkel de b als antwoord produceren, meer heb je ook niet nodig om binnen te komen).

1000x hashen vergroot enkel de kans op een collision, alhoewel het wachtwoord moeilijker te achterhalen wordt, wordt het binnenkomen enkel maar makkelijker...
De kans op collisions is echt verwaarloosbaar. Voor SHA512 zijn geen aanvallen bekent om efficient collisions te genereren. Daarnaast zijn er 2^512 = 134078079299425970995740249982058461274793658205923933777235614437
21764030073546976801874298166903427690031858186486050853753882811946569946433649006084096 mogelijkheden voor een hash. Oftewel de kans dat jij per ongeluk een colisison vind is echt nihil. Het stretchten is echt heel belangrijk tegenwoordig. Als ik de database leeg trek dan weet ik de salt en heb ik in een half uur alles tot 8 chars door mijn videokaart laten berekenen. Als je hem 10000 keer achter elkaar had gehashed had het al 1000 keer langer geduurd. Je moet er gewoon van uitgaan dat het iemand lukt om die salt te achterhalen.

Stretchen is iets wat je in elke secure programming course tegen zult komen.

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Anoniem: 289377 schreef op vrijdag 28 januari 2011 @ 22:12:
[...]
Als ik de database leeg trek dan weet ik de salt
??? En dan heb je het over secure computing ??? Salt enkel laten bestaan uit dbase entries?
Da's geen secure computing imho.
en heb ik in een half uur alles tot 8 chars door mijn videokaart laten berekenen. Als je hem 10000 keer achter elkaar had gehashed had het al 1000 keer langer geduurd.
De getoonde methode is fout. Wat er nu gebeurt is dat de hash van de hash 10.000x berekend wordt, of 100.000x voor mijn part. Daar zijn perfecte rainbowtabellen op te maken. Het is niets anders dan enkel maar een hash van een hash. Door die rainbow tabellen blaast een hacker zo door 9.999x hashen heen.

Enkel als elke keer de salt(liefst nog met een ietwat random component) toegepast wordt bij de hashing blokkeer je rainbow tables. Key strengtening kan je maar op een paar goede manieren doen, pak de verkeerde en je bent enkel bezig met key weakening

Maarja, dat is net zoiets als parametrized query's wat iemand hier eerder postte. Dat is imho juist geen onderdeel van secure computing. Daarmee gooi je enkel een gedeelte dicht.
Je system calls / externe calls staan nog steeds wijd open.
Gewoon al je input sanitizen dan heb je geen parametrized query's nodig. Dan gebruik je ze enkel nog maar vanuit performance oogpunt en niet vanuit secure computing oogpunt.

Acties:
  • 0 Henk 'm!

  • Aloys
  • Registratie: Juni 2005
  • Niet online
Trouwens denk ik nou simpel ivm. Sql-injection of kun je bij je query ook gewoon simpelweg intval(x) gebruiken? Ik kies daar altijd voor bij query's waarbij ik zeker weet dat de input een geheel getal moet zijn. Heb je ook geen kans dat er gekke tekens meekomen. Probeert iemand toch wat, dan krijg je gewoon een verkeerd getal. :)

Acties:
  • 0 Henk 'm!

  • Nijn
  • Registratie: Januari 2005
  • Laatst online: 08:13
code:
1
2
3
4
5
hash = sha512(password + salt);

for (int i = 0; i < 1000; i++) {
    hash = sha512(hash);
}


Er zijn een aantal mogelijkheden om een wachtwoord te achterhalen. De 3 die er nu toe doen:
- Rainbow tables
- Weakness in het algoritme misbruiken (waaronder kans op collissions)
- Brute Forcen.

Die 3 wil je dus zo moeilijk mogelijk maken.

Rainbow tables
Zoals je ziet wordt er een salt gebruikt. Gebruik die salt op de juiste manier (iedere user eigen random salt + lang genoeg) en je bent vrijwel van rainbow tables af.

Weakness
Er wordt hier SHA-512 gebruikt. Dat is dus het SHA2 algoritme. Hiervoor zijn geen bekende weaknesses die in dit geval problemen zullen opleveren. Door gebruik te maken van een 512 bit hash (waar MD5 bijvoorbeeld slechts 128 bits heeft), is je kans op collissions enorm klein geworden. Vrijwel verwaarloosbaar.

Brute Force
Brute Force is essentieel om aan te denken. De success rate is 100%, daar kun je niets aan doen. Wat je wel kunt doen is het proces zo veel mogelijk vertragen. Dat begint met een goeie password policy. Maar daarmee kom je er niet. Een wachtwoord van minimaal 16 tekens met minstens 5 verschillende leestekens gaan je klanten tenslotte niet leuk vinden. Vervolgens heb je nog een heel sterk middel: Stretching. Daarvan is bovenstaande code een voorbeeld. Wat er gebeurt is simpel maar doeltreffend.

Je neemt het wachtwoord + de salt. Die hash je.
Het resultaat daarvan hash je opnieuw
Het resultaat daarvan hash je opnieuw
Het resultaat daarvan hash je opnieuw
Het resultaat daarvan hash je opnieuw
etc etc etc.

Je vergroot hiermee de kans op collissions vrijwel niet, maar vergroot de tijd die een brute-force attack in beslag neemt met (bijvoorbeeld) 1000 maal.

Acties:
  • 0 Henk 'm!

  • Maaark
  • Registratie: Juli 2008
  • Laatst online: 02-06 11:35
Nijn schreef op zaterdag 29 januari 2011 @ 00:19:


Je neemt het wachtwoord + de salt. Die hash je.
Het resultaat daarvan hash je opnieuw
Het resultaat daarvan hash je opnieuw
Het resultaat daarvan hash je opnieuw
Het resultaat daarvan hash je opnieuw
etc etc etc.

Je vergroot hiermee de kans op collissions vrijwel niet, maar vergroot de tijd die een brute-force attack in beslag neemt met (bijvoorbeeld) 1000 maal.
Is dit niet beter?

Je neemt het wachtwoord + salt, die hash je
daar gooi je weer de salt bij en hash je
etc etc etc

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Even een dumpje uit m'n bookmarks; want er wordt hier nogal wat geblaat...

You Want Salt With That? Part One: Security vs Obscurity
You Want Salt With That? Part Two: We Need A Hash
You Want Salt With That? Part Three: Salt The Hash
You Want Salt With That? Part Four: Challenge-Response
How to manage a PHP application's users and passwords
How To Safely Store A Password
Nijn schreef op zaterdag 29 januari 2011 @ 00:19:
Je neemt het wachtwoord + de salt. Die hash je.
Het resultaat daarvan hash je opnieuw
Het resultaat daarvan hash je opnieuw
Het resultaat daarvan hash je opnieuw
Het resultaat daarvan hash je opnieuw
etc etc etc.

Je vergroot hiermee de kans op collissions vrijwel niet, maar vergroot de tijd die een brute-force attack in beslag neemt met (bijvoorbeeld) 1000 maal.
Heb je daar een bron van? Want je praat onzin; sterker: best case scenario (en vergeet dat maar rustig) is 'ie hooguit even goed; worst-case (en meest likely, als in: you can bet your ass on it) verklein je je entropie en maakt je dat bij elke loop erger en erger. Het is dus zéér zeker niet veiliger om een hash te re-hashen, laat staan tientallen of honderden of meer keren...

[ Voor 34% gewijzigd door RobIII op 29-01-2011 01:38 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • glrfndl
  • Registratie: Juni 1999
  • Niet online
RobIII schreef op zaterdag 29 januari 2011 @ 01:08:
[...]
Heb je daar een bron van? Want je praat onzin; sterker: best case scenario (en vergeet dat maar rustig) is 'ie hooguit even goed; worst-case (en meest likely, als in: you can bet your ass on it) verklein je je entropie en maakt je dat bij elke loop erger en erger. Het is dus zéér zeker niet veiliger om een hash te re-hashen, laat staan tientallen of honderden of meer keren...
Dat is wel heel stellig :)
Stretching/strengthening wordt namelijk wel degelijk toegepast, ook in grote/bekende projecten (dat hoeft natuurlijk nog niks te zeggen). Op wikipedia staat wel wat info: Wikipedia: Key strengthening


Edit: ik wil niet beweren dat dit wel (of niet) een goed iets is om te doen, daar waag ik mij niet aan :)

[ Voor 6% gewijzigd door glrfndl op 29-01-2011 10:11 ]

Prepare for unforeseen consequences


Acties:
  • 0 Henk 'm!

  • Aloys
  • Registratie: Juni 2005
  • Niet online
Kan je dan niet beter bij iedere rehash de salt ook opnieuw meegeven?
code:
1
2
3
4
5
hash = sha512(password + salt);

for(int i=0; i<100; i++) {
    hash = sha512(hash + salt);
}

Acties:
  • 0 Henk 'm!

  • PolarBear
  • Registratie: Februari 2001
  • Niet online
RobIII schreef op zaterdag 29 januari 2011 @ 01:08:
Heb je daar een bron van? Want je praat onzin; sterker: best case scenario (en vergeet dat maar rustig) is 'ie hooguit even goed; worst-case (en meest likely, als in: you can bet your ass on it) verklein je je entropie en maakt je dat bij elke loop erger en erger. Het is dus zéér zeker niet veiliger om een hash te re-hashen, laat staan tientallen of honderden of meer keren...
Het punt is dat je het wachtwoord + de salt X keer hasht. Om binnen te komen moet je dus niet alleen een wachtwoord + salt bruteforcen maar ook nog eens zorgen dat je X keer hasht. Een collision vinden met het X keer gehashte salt + wachtwoord heb je niets aan, want als je die invoert wordt bij validatie die collision weer X keer gehasht waardoor er iets anders uit komt. Het is dus een vertragingstactiek omdat je met nog een variabele rekening moet houden.

Zie ook Wikipedia: PBKDF2

[ Voor 3% gewijzigd door PolarBear op 29-01-2011 11:38 ]


Acties:
  • 0 Henk 'm!

  • EdwinG
  • Registratie: Oktober 2002
  • Laatst online: 27-05 15:59
Gomez12 schreef op vrijdag 28 januari 2011 @ 23:38:
Gewoon al je input sanitizen dan heb je geen parametrized query's nodig. Dan gebruik je ze enkel nog maar vanuit performance oogpunt en niet vanuit secure computing oogpunt.
Dit is absoluut een verkeerde instelling. Hoe wil je bijvoorbeeld een tekstveld sanitizen zonder de functionaliteit te beperken? Waarom zou in bijvoorbeeld een nieuwsbericht geen ', ", \ of andere tekens voor mogen komen?

Deze tekens kun je, met dynamische queries, niet zonder correcte encoding/escaping in de querie opnemen. Alleen sanitizen is in veel gevallen dus niet veilig te krijgen, je zult altijd escaping/encoding of parameterized queries nodig hebben.

[edit]
Voor de duidelijkheid, het gebruik van parameterized queries bied geen enkele bescherming tegenover o.a. Cross-site scripting, cross-site request forgery en vele andere aanvallen/beveiligingsrisico's.

[ Voor 12% gewijzigd door EdwinG op 29-01-2011 15:57 . Reden: toevoeging over xss e.d. ]

Bezoek eens een willekeurige pagina


Acties:
  • 0 Henk 'm!

  • EdwinG
  • Registratie: Oktober 2002
  • Laatst online: 27-05 15:59
Ik vroeg me al af wanneer iemand PBKDF2 zou komen. :)

Een voorbeeld van php-code voor PBKDF2 (inclusief uitleg):
http://www.itnewb.com/v/E...g-the-RSA-PBKDF2-Standard

edit:
php-voorbeeld ook maar toegevoegd aan de wikipagina

[ Voor 7% gewijzigd door EdwinG op 29-01-2011 13:41 ]

Bezoek eens een willekeurige pagina


Acties:
  • 0 Henk 'm!

  • skabouter
  • Registratie: Oktober 2000
  • Laatst online: 02-06 13:41

skabouter

Skabouter

Even wat quotes en ophelderingen:
beany schreef op donderdag 27 januari 2011 @ 21:00:
[...]
3
Maar je kan ook gaan vertragen.
1x foute login = 0 seconden wachttijd voor volgende poging is toegestaan
2e keer foute login = 3 seconden
3e keer foute login = 9 seconden
4e keer foute login = 28 seconden
etc
Dit is inderdaad de manier om delayed-login-fails in te bouwen, om dit met secondes te doen is echter wel heel cru voor de gebruiker (zie ook hieronder)
ReenL schreef op donderdag 27 januari 2011 @ 21:06:
"Is het gebruiken van een sleep() bij het inloggen noodzakelijk? Aangezien het liefst alles natuurlijk zo snel mogelijk moet gaan?"
Let op dat je dit dan ook bij een gelukte login moet doen. Anders kan een bot elke response die langer dan een halve seconde duurt negeren en een nieuwe request sturen en de response simpel negeren.
Waarom moet je dit ook voor gelukte login's toepassen? Wat je moet doen is het koppelen aan de IP van de "bezoeker". Stel ik log in op site x en het gaat goed >> geen delay, stel hacker Y probeert in te loggen en dit mislukt steeds >> steeds sleep(($poging_nr * $poging_nr ) * 2 ms) voor het gebruikte IP. Hiermee vertraag je het aantal pogingen per gebruikt IP.
Maaark schreef op donderdag 27 januari 2011 @ 21:18:
@beany: Dat is inderdaad een goed plan :) Alleen heb ik zelf ook wel eens dat ik 10x moet raden welk wachtwoord ik gebruik... dan zou deze sleep tijd een beetje erg onvriendelijk zijn?
Om deze reden moet je ook geen seconden gebruiken maar mili seconden, dit is voor de gebruiker nouwelijks merkbaar (in jou voorbeeld bij de laatste poging 10 * 10 = 100 * 2 ms = 200ms. deze ms zijn echter voor een hacker erg vervelend als hij 1000 request moet doen ((1000 * 1000) * 2ms = 33.33 minuten)
CptChaos schreef op donderdag 27 januari 2011 @ 21:25:
[...]
Tja, waarom zou je onnodig vertragen? Dat werkt alleen maar avrechts op "de werking" en de userexperience van de site an sich.
Zie hierboven
dev10 schreef op donderdag 27 januari 2011 @ 21:31:
[...]
Nee, ik vind het onwenselijk dat ik bij het inloggen een x aantal seconden moet wachten.
Zie hierboven
Bv202 schreef op donderdag 27 januari 2011 @ 22:25:
Wat ik even niet snap hier is wat het nut precies is van de sleep()-functie te gebruiken bij het inloggen. Wat draagt dit bij aan de veiligheid?
Ik hoop dat deze post dit een beetje duidelijk maakt, je probeert dus de pogingen van een mogelijke "aanval" doormiddel van brute forece login pogingen te vertragen door elke mislukte login poging langer te laten duren.

[ Dislect ]


Acties:
  • 0 Henk 'm!

  • Bv202
  • Registratie: Oktober 2006
  • Laatst online: 14-11-2021
Ok, bedankt voor de uitleg :)

Wat is eigenlijk de beste manier om een salt op te slaan? Tot nu toe deed ik dit:
- Random salt berekenen
- Salt toevoegen aan wachtwoord en van dit geheel een hash maken
- Salt toevoegen aan hash
- Opslaan in database

Is dit een goede manier om de salt op te slaan? Of is het veiliger om in plaats van een random salt te berekenen en deze op te slaan, een salt te berekenen op basis van een aantal unieke dingen (gebruikersnaam etc.). Het voordeel is dan dat, als iemand toegang krijgt tot je databasegegevens maar niet tot je code, de salt onbekend is voor die persoon. Maar het probleem is dan wel dat ook die unieke gegevens zoals gebruikersnamen wel eens kunnen veranderen.

Wat is de gebruikelijke manier om dit te doen?

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
EdwinG schreef op zaterdag 29 januari 2011 @ 13:19:
[...]
Dit is absoluut een verkeerde instelling. Hoe wil je bijvoorbeeld een tekstveld sanitizen zonder de functionaliteit te beperken? Waarom zou in bijvoorbeeld een nieuwsbericht geen ', ", \ of andere tekens voor mogen komen?
Tja, hoe wil jij een tekstveld van javascript input gaan ontdoen door enkel parametrized query's te gebruiken?
Wat ik bedoelde is dat enkel parametrized query's geen enkel beveiligingsvoordeel geven. Het is of de hele aanpak die hoort bij encoding/escaping/filtering waardoor parametrized query's redelijk nutteloos worden.

Je moet tig methodes toepassen en parametrized query's is daar hooguit 1 van. Maar praktisch wordt die als het goed is al gedekt door een combinatie van je andere methodes waardoor het overbodig wordt qua secure computing.
Deze tekens kun je, met dynamische queries, niet zonder correcte encoding/escaping in de querie opnemen. Alleen sanitizen is in veel gevallen dus niet veilig te krijgen, je zult altijd escaping/encoding of parameterized queries nodig hebben.
Voor enkel je dbase stuk gaat dit op. Dan liggen nog steeds je FS-functies open, je system calls liggen open, je connecties naar derden liggen open, je html-output ligt open etc. etc.

Parametrized query's is enkel een onderdeel, absoluut niet de heilige graal waar het veelal voor afgeschilderd wordt.

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
skabouter schreef op zaterdag 29 januari 2011 @ 13:47:
[...]
Waarom moet je dit ook voor gelukte login's toepassen?
Theorie achter dit ook voor gelukte login's toepassen is dat een systeem anders kan zien of een login gelukt of gefaald is. Maar door gewoon een totale block te genereren voor de blocktijd heb je hier geen last van.
Al komt iemand met een succesvolle login in de blocktijd dan nog wordt hij afgekeurd (want hij zit in de blocktijd)

Het berust op het idee dat als iemand van 1000 terminals tegelijk probeert in te loggen dat hij dan terwijl terminal 1 in de blocktijd zit op terminal 2 een poging kan wagen. Reageert terminal 2 dan sneller dan zou je een succesvolle login hebben. Maarja, daarom ook blocks op account nivo inbouwen. Dan zit hij op terminal 2 nog steeds in de blocktijd aangemaakt door terminal 1.
Bv202 schreef op zaterdag 29 januari 2011 @ 14:09:
Wat is eigenlijk de beste manier om een salt op te slaan? Tot nu toe deed ik dit:
- Random salt berekenen
- Salt toevoegen aan wachtwoord en van dit geheel een hash maken
- Salt toevoegen aan hash
- Opslaan in database
In wezen is je laatste stap je grootste fout. Je moet een gedeelte van je salt op een extern iets plaatsen ( buiten je dbase/www-root, op een externe server oid ). Momenteel als iemand je dbase heeft heeft hij alles wat nodig is om het te breken.
Maar het probleem is dan wel dat ook die unieke gegevens zoals gebruikersnamen wel eens kunnen veranderen.
Dat is geen probleem, dan verandert je salt voor die desbetreffende gebruiker gewoon mee.
Wat is de gebruikelijke manier om dit te doen?
Gebruikelijke manier voor een simpele salt is om iets van de gebruiker te pakken (zodat het per gebruiker verschillend is) en iets onbekends te pakken (dus iets wat niet in je dbase staat, maar bijv buiten je webroot)

Op deze manier heeft hij niets aan enkel je dbase hij mist nog steeds een stukje salt (het onbekende buiten je webroot)
Als hij al je complete salt weet te bemachtigen dan moet hij alsnog per gebruiker gaan "kraken" (want de uiteindelijk gebruikte salt is per gebruiker verschillend)

Acties:
  • 0 Henk 'm!

  • ReenL
  • Registratie: Augustus 2010
  • Laatst online: 14-09-2022
skabouter schreef op zaterdag 29 januari 2011 @ 13:47:
[...]

Waarom moet je dit ook voor gelukte login's toepassen?
Oke, stel je bent een incrementele sleep aan het doen, in microseconden, of whatever. En je doet geen timeout bij een succesvolle login.

Met deze kennis maak ik vervolgens een bot:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
$client = new SomeHttpClient();
$generator = new PasswordGenerator();
$success = 'Welkom';

$pwd = $generator->next();
$timer = new Timer();
$result = $client->post(array('user' => $user, 'password' => $pwd));

$client->setTimeout($timer->get() + 1000); // Extra seconde voor echte latency.
unset($timer);

while ( !$result->contains($success) ) {
    $pwd = $generator->next();
    $result = $client->post(array('user' => $user, 'password' => $pwd));
}

echo 'The password for '.$user.' is '.$pwd.'.';


Ik weet toch al dat wanneer mijn poging lukt, ik een "instant" resultaat krijg. Dus waarom zou ik langer als een seconde extra (bovenop de eerste request tijd) wachten op een resultaat? Ik weet dan toch dat je me aan het neppen ben.

Daarom moet je een vertraging _altijd_ doen als je hem doet.

Echter, is het niet wenselijk om een sleep zoals ik eerder aangaf liever een IP/Account ban.

Een echte hacker schrijft namelijk een programma in meerdere threads en die maakt threads aan zolang hij nog geen response heeft gekregen. Sleeps en locks op basis van ip zouden alleen zin hebben als de hacker niet de beschikking heeft over een groot aantal ip's en daar kun je niet vanuit gaan, dus, of je het leuk vind of niet, gebruikersaccounts (tijdelijk) locken is de enige manier waar een hacker niet omheen kan.

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
ReenL schreef op zaterdag 29 januari 2011 @ 15:22:
[...]
Ik weet toch al dat wanneer mijn poging lukt, ik een "instant" resultaat krijg. Dus waarom zou ik langer als een seconde extra (bovenop de eerste request tijd) wachten op een resultaat? Ik weet dan toch dat je me aan het neppen ben.

Daarom moet je een vertraging _altijd_ doen als je hem doet.

Echter, is het niet wenselijk om een sleep zoals ik eerder aangaf liever een IP/Account ban.
En met een IP/Account ban hoef je dus die vertraging helemaal niet meer te doen. Als jij elke seconde een poging doet dan garandeer ik voor zo goed als 100% dat jouw correcte inlogpoging in een banperiode valt waardoor jij hem dus nog steeds niet ziet. Je hebt dan een leuke poging tot een DDOS gedaan, maar geen succesvolle inloghack.

Acties:
  • 0 Henk 'm!

  • EdwinG
  • Registratie: Oktober 2002
  • Laatst online: 27-05 15:59
Gomez12 schreef op zaterdag 29 januari 2011 @ 14:42:
Tja, hoe wil jij een tekstveld van javascript input gaan ontdoen door enkel parametrized query's te gebruiken?
Niet, daar zijn parameterized queries totaal niet voor bedoeld. Tegen Cross-site scripting is consequent/structureel uitgevoerde uitvoerencoding de belangrijkste beveiliging. Invoervalidatie kan helpen, maar wederom niet voldoen. Bijvoorbeeld op dit forum, het moet gewoon mogelijk zijn om een JavaScript-codevoorbeeld te plaatsen, dus invoervalidatie kan niet hier niet voldoende beschermen tegen cross-site scripting.

Voor de duidelijkheid heb ik die nuance toevoegd aan mijn vorige post.
Gomez12 schreef::
Wat ik bedoelde is dat enkel parametrized query's geen enkel beveiligingsvoordeel geven.
Als het gebruik van parameterized query's de enige geïmplementeerde beveiliginsmaatregel is, is de website inderdaad zo lek als een mandje. Maar dat wil niet zeggen dat ze "geen enkel" beveiligingsvoordeel geven.

Uit je eerdere bericht:
Gomez12 schreef::
Gewoon al je input sanitizen dan heb je geen parametrized query's nodig.
Dit klopt dus niet. Het is inderdaad mogelijk door een combinatie van sanitizen en escaping/encoding om de databaseinteractie te beveiligen, maar alleen sanitizen is niet voldoende.
Gomez12 schreef::
Parametrized query's is enkel een onderdeel, absoluut niet de heilige graal waar het veelal voor afgeschilderd wordt.
Hier kan ik het alleen maar mee eens zijn :) Ik zal dan ook nooit beweren dat ze alle beveiligingsproblemen kunnen oplossen.

Bezoek eens een willekeurige pagina


Acties:
  • 0 Henk 'm!

Anoniem: 289377

Gomez12 schreef op vrijdag 28 januari 2011 @ 23:38:
[...]

??? En dan heb je het over secure computing ??? Salt enkel laten bestaan uit dbase entries?
Da's geen secure computing imho.
Waar wil je het nog meer van af laten hangen. Het is een webserver, je moet er gewoon altijd vanuit gaan dat deze geroot is. Hij biedt services aan op het internet en is daarmee een uitstekend doelwit voor mensen met een 0day voor 1 van jou services. Welke salt je ook bedenkt, jou aanvaller heeft ook deze mogelijkheden. Waar je je tegen wilt beschermen is als iemand alle hashes bemachtigd, en vervolgens niet efficiënt user password kan achterhalen.
De getoonde methode is fout. Wat er nu gebeurt is dat de hash van de hash 10.000x berekend wordt, of 100.000x voor mijn part. Daar zijn perfecte rainbowtabellen op te maken. Het is niets anders dan enkel maar een hash van een hash. Door die rainbow tabellen blaast een hacker zo door 9.999x hashen heen.
Nee, hier zijn geen rainbow tables voor te maken. Je moet namelijk dan voor elke gebruiker een apparte rainbow table maken. Gezien het feit dat een rainbow gemakkelijk tegen de 1 terabyte aan zit is dit niet rendabel. Als ik nu als aanvaller wil bruteforcen moet ik de salt pakken, hier een dictonary woord voorplakken, vervolgens dat 10000 keer hashen voordat ik weet of deze gelijk is aan de hash in de database. En dat dan voor elk dictionary woord. En dat dan ook nog voor elke user verschillend omdat de salt bij iedereen anders is.
Enkel als elke keer de salt(liefst nog met een ietwat random component) toegepast wordt bij de hashing blokkeer je rainbow tables. Key strengtening kan je maar op een paar goede manieren doen, pak de verkeerde en je bent enkel bezig met key weakening
Ik ben benieuwd hoe jij elke keer random componenten aan een salt kan toevoegen, hij moet wel gelijk zijn aan de eerste keer dat je het wachtwoord hashede namelijk (met die salt), anders klopt de uiteindelijke hash niet.
Heb je daar een bron van? Want je praat onzin; sterker: best case scenario (en vergeet dat maar rustig) is 'ie hooguit even goed; worst-case (en meest likely, als in: you can bet your ass on it) verklein je je entropie en maakt je dat bij elke loop erger en erger. Het is dus zéér zeker niet veiliger om een hash te re-hashen, laat staan tientallen of honderden of meer keren...
Je verkleint de entropie niet. Het is een hashing algoritme. Het doel hiervan is dat elke bit invoer invloed heeft op elke uitvoer bit (het is geen 1-1 mapping). Dat is juist de kracht van een hashings algortime (of AES for that matter). Als je aan de hand van de uitvoer iets zou kunnen zeggen over de invoer is het een slecht hashing algoritme.

Ik zag nog ergens dit voorbij komen:
code:
1
2
3
for (i = 0; i < 10000; i++) {
    hash = sha512(salt + hash);
}

Ja dit kun je doen, voegt niet heel veel toe maar het kan ook geen kwaad. Het gaat er in die for lus om dat je het proces vertraagt voor iemand met een snelle GPU en de salts + uiteindelijke hashes heeft. Maar voor iedereen die niet overtuigd is heb ik twee hashes:

code:
1
2
8c788342f3d2fcbe093171a8001b0e4cdff02bcc64a0af9edf5c9988ba694383bd07ff5b0cfee252f17be3bf7c8f7cdb128ead600d12a2a1a7f7b5a04950b931
b7759a1a81e81fa9533a387361fdafcb5ded445edc33207cd9767f41c7bf154735b7a8051108448b9d8cfa27c1c140496d92faa1b0651bb1d4350258bdfa6568

De hashes zijn als volgt gegenereerd:
Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/python

import hashlib

salt = "xWvVrckgpWXf)udBvXxXTajY<2oNEBpBq7gzmvgBhTpMsEdbeJ"

print hashlib.sha512("****" + salt).hexdigest()

stretched = "****" + salt

for i in range(10000):
    stretched = hashlib.sha512(stretched).hexdigest()

print stretched


Op de plek van de **** staat natuurlijk het wachtwoord. De wachtwoorden zijn gewone korte Nederlandse woorden en zouden in elk woordenboek moeten staan. De eerste die de wachtwoorden post wint :)

Acties:
  • 0 Henk 'm!

  • EdwinG
  • Registratie: Oktober 2002
  • Laatst online: 27-05 15:59
Anoniem: 289377 schreef op zaterdag 29 januari 2011 @ 16:24:
Op de plek van de **** staat natuurlijk het wachtwoord. De wachtwoorden zijn gewone korte Nederlandse woorden en zouden in elk woordenboek moeten staan. De eerste die de wachtwoorden post wint :)
Een eenvoudig scriptje leverde dit op (in combinatie met 'time') voor de eerste hash. De tweede is nog aan het rekenen, wat natuurlijk de kracht meteen aantoond:
code:
1
2
3
4
5
stoel

real    0m0.394s
user    0m0.378s
sys 0m0.015s


Het betrokken woord was overigens nummer 147372 uit mijn woordenlijst, afkomstig van http://www.opentaal.org/bestanden (3- Woordenlijst v 2.00g - bronbestanden)

Bezoek eens een willekeurige pagina


Acties:
  • 0 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 10:16

Matis

Rubber Rocket

Is daarmee beweren dat het her-hashen van wachtwoorden wel degelijk een positieve invloed heeft op de kraakbaarheid?

Want op de vorige pagina werd volgens mij het tegendeel beweerd.

[ Voor 27% gewijzigd door Matis op 29-01-2011 17:37 ]

If money talks then I'm a mime
If time is money then I'm out of time


Acties:
  • 0 Henk 'm!

  • skabouter
  • Registratie: Oktober 2000
  • Laatst online: 02-06 13:41

skabouter

Skabouter

ReenL schreef op zaterdag 29 januari 2011 @ 15:22:
[...]

Ik weet toch al dat wanneer mijn poging lukt, ik een "instant" resultaat krijg. Dus waarom zou ik langer als een seconde extra (bovenop de eerste request tijd) wachten op een resultaat? Ik weet dan toch dat je me aan het neppen ben.

Daarom moet je een vertraging _altijd_ doen als je hem doet.

Echter, is het niet wenselijk om een sleep zoals ik eerder aangaf liever een IP/Account ban.

Een echte hacker schrijft namelijk een programma in meerdere threads en die maakt threads aan zolang hij nog geen response heeft gekregen. Sleeps en locks op basis van ip zouden alleen zin hebben als de hacker niet de beschikking heeft over een groot aantal ip's en daar kun je niet vanuit gaan, dus, of je het leuk vind of niet, gebruikersaccounts (tijdelijk) locken is de enige manier waar een hacker niet omheen kan.
Ik geloof dat ik mijn post niet helemaal duidelijk heb geschreven, waarvoor mijn excuses.

Wat ik bedoelde is dat tijdens de "sleep" tijd, de gebruiker sowieso niet kan inloggen op het gebruikte IP (dus een soort van tijdelijke IP ban) Het script dat jij gebruikt werkt dus niet, want je zult als de eerste +/- 22 loginpogingen niet gelukt zijn altijd langer dan 1000 seconden moeten wachten voordat je überhaupt weer een login poging kan doen die succesvol is.

Dit heeft als voordeel dat je het probleem met proxy gebruikers, zoals eerder aangegeven, niet ervoor kan zorgen dat ineens een publiek IP voor alle gebruikers geblokkeerd raakt.

[ Dislect ]


Acties:
  • 0 Henk 'm!

  • P.O. Box
  • Registratie: Augustus 2005
  • Niet online
Even een vraagje tussendoor m.b.t. dit onderwerp...

ik gebruik wel eens de .htaccess file om delen van de website te beveiligen. Als ik voorgaande allemaal zo lees, vraag ik me af: is beveiliging via de .htaccess file aan te raden?

Acties:
  • 0 Henk 'm!

  • EdwinG
  • Registratie: Oktober 2002
  • Laatst online: 27-05 15:59
Matis schreef op zaterdag 29 januari 2011 @ 17:36:
Is daarmee beweren dat het her-hashen van wachtwoorden wel degelijk een positieve invloed heeft op de kraakbaarheid?

Want op de vorige pagina werd volgens mij het tegendeel beweerd.
Ik neem aan dat je "bewezen" bedoeld (in plaats van "beweren").
Ja, het her-hashen van wachtwoorden heeft wel degelijk een positieve invloed op de kraakbaarheid (dat wil zeggen, het gaat langer duren).

Voor diegenen die bang zijn voor collisions, kijk nog eens naar dit bericht:
Anoniem: 289377 in "\[php, mysql] Hoe website beveiligen?"
P.O. Box schreef op zaterdag 29 januari 2011 @ 18:30:
Even een vraagje tussendoor m.b.t. dit onderwerp...

ik gebruik wel eens de .htaccess file om delen van de website te beveiligen. Als ik voorgaande allemaal zo lees, vraag ik me af: is beveiliging via de .htaccess file aan te raden?
Hangt er van af wat je probeert te beveiligen. Als je bijvoorbeeld (server-side)includes hebt die je (door hosting bijvoorbeeld) niet buiten de webroot kunt plaatsen, kan het afschermen van de includes-directory met behulp van .htaccess een mooie extra beveiliging zijn.

Ook het vragen om een naam/wachtwoord om bepaalde delen van de website te benaderen kan via .htaccess worden uitgevoerd. Of dit qua onderhoud ook wenselijk is, is iets dat je alleen zelf kunt bepalen.

Let wel op dat je met .htaccess lang niet alle nodige beveiligingsmaatregelen kunt treffen.

[ Voor 41% gewijzigd door EdwinG op 29-01-2011 18:45 ]

Bezoek eens een willekeurige pagina


Acties:
  • 0 Henk 'm!

  • wackmaniac
  • Registratie: Februari 2004
  • Laatst online: 08:28
P.O. Box schreef op zaterdag 29 januari 2011 @ 18:30:
Even een vraagje tussendoor m.b.t. dit onderwerp...

ik gebruik wel eens de .htaccess file om delen van de website te beveiligen. Als ik voorgaande allemaal zo lees, vraag ik me af: is beveiliging via de .htaccess file aan te raden?
Op het gebied van bestandsbeveiliging; prima! Apache zal de gebruiker namelijk geen toegang geven tot de bestanden via de webserver-interface. Zover ik weet zitten hier nog geen bekende flaws in. Het beschermd je natuurlijk niet tegen mensen die via bv ssh of ftp op je webserver rondneuzen.

Read the code, write the code, be the code!


Acties:
  • 0 Henk 'm!

  • EdwinG
  • Registratie: Oktober 2002
  • Laatst online: 27-05 15:59
Anoniem: 289377 schreef op zaterdag 29 januari 2011 @ 16:24:
Op de plek van de **** staat natuurlijk het wachtwoord. De wachtwoorden zijn gewone korte Nederlandse woorden en zouden in elk woordenboek moeten staan. De eerste die de wachtwoorden post wint :)
EdwinG schreef op zaterdag 29 januari 2011 @ 17:28:
Een eenvoudig scriptje leverde dit op (in combinatie met 'time') voor de eerste hash. De tweede is nog aan het rekenen, wat natuurlijk de kracht meteen aantoond:
code:
1
2
3
4
5
stoel

real    0m0.394s
user    0m0.378s
sys 0m0.015s


Het betrokken woord was overigens nummer 147372 uit mijn woordenlijst, afkomstig van http://www.opentaal.org/bestanden (3- Woordenlijst v 2.00g - bronbestanden)
En nu ook het tweede antwoord. (Ik had een fout gemaakt bij het oplossen, dus duurde iets langer)
code:
1
2
3
4
5
koffie

real    36m37.092s
user    36m24.053s
sys 0m0.117s


Dit woord kwam een stuk eerder voor in de woordenlijst: positie 91711

Bezoek eens een willekeurige pagina


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Nou is een half uur ook nog niet echt schokkend, en dat toont meteen het grootste probleem als je alles technisch op orde hebt: Het gros van de gebruikers heeft een deprimerend slecht wachtwoord. :X

{signature}


Acties:
  • 0 Henk 'm!

  • HuHu
  • Registratie: Maart 2005
  • Niet online
Voutloos schreef op zaterdag 29 januari 2011 @ 20:30:
Nou is een half uur ook nog niet echt schokkend, en dat toont meteen het grootste probleem als je alles technisch op orde hebt: Het gros van de gebruikers heeft een deprimerend slecht wachtwoord. :X
Ik heb eens een controle gedaan op een grote Nederlandse website, ongeveer 1 op de 500 gebruikers had als wachtwoord "geheim". Verder had ongeveer 1 op de 500 als wachtwoord z'n gebruikersnaam. Daarnaast kwam ook het wachtwoord "wachtwoord" erg vaak voor.

Het is daarom voor een hacker vaak eenvoudiger om het wachtwoord te fixeren en verschillende gebruikersnamen te proberen. De gebruikersnamen kun je meestal ook nog eenvoudig verkrijgen.

Acties:
  • 0 Henk 'm!

Anoniem: 289377

Voutloos schreef op zaterdag 29 januari 2011 @ 20:30:
Nou is een half uur ook nog niet echt schokkend, en dat toont meteen het grootste probleem als je alles technisch op orde hebt: Het gros van de gebruikers heeft een deprimerend slecht wachtwoord. :X
Dat is helemaal waar, maar daar kun jij als programmeur niks aan doen. Wat je wel kunt doen is het een hacker zo moeilijk mogelijk maken mocht hij de hashes in bezit krijgen.

Omdat je per user salt moet hij elke hash appart kraken. Als je dezelfde hash voor alles gebruikt dan kun je gewoon gaan bruteforcen en kijken of 1 van de users toevallig dat wachtwoord heeft. Nu moet hij echt alle users appart bij langs. En zoals je ziet duurt het wel even. Als iemand een beetje een sterk wachtwoord heeft dan moet je dus alle combinaties van hoofdletters, kleine letters en cijfers langs. Als het wachtwoord gestretched is dan is dit nooit rendabel. Die 10000 in mijn voorbeeld kun je makkelijk op 10000000 zetten als je webserver dat aan kan. Dan maak je het probleem nog eens 1000 moeilijker.

Ze hebben een tijd geleden op een beurs gevraagd (non-technisch) aan mensen of ze hun wachtwoord mochten weten. 30% vond dat sowieso geen probleem, en 70% wou het wel ruilen tegen een reep chocola :+

Omdat veel websites hun password policy nog niet op orde hebben (MD5, geen stretching/salt enz, of gewoon plain text zoals marktplaats 8)7), genereer ik gewoon voor elke site een >25 tekens lang random wachtwoord.

Edit:
Oja als iemand nog een manier weet hoe je het brutforcen kunt versnellen, en waarom het stretchen geen zin heeft (ik hoorde op de vorige pagina dingen als entropie verkleinen), dan zou ik graag willen weten hoe je dit zou doen. Ik moet nog 2 crypto papers schrijven dit semester, en ik zoek nog een onderwerp :)

[ Voor 13% gewijzigd door Anoniem: 289377 op 30-01-2011 09:33 ]


Acties:
  • 0 Henk 'm!

  • PolarBear
  • Registratie: Februari 2001
  • Niet online
EdwinG schreef op zaterdag 29 januari 2011 @ 18:35:
[...]
Voor diegenen die bang zijn voor collisions, kijk nog eens naar dit bericht:
Anoniem: 289377 in "\[php, mysql] Hoe website beveiligen?"
Collissions zijn niet zo intressant. Stel je hasht het wachtwoord 1000x met SHA512 en daar het volgende uit:
8d847e01d22baa969f71fa362b4de21c9e13c7882bcea13ba5c6a8ae0d71fc8c9700c82e0087a65c8b37bd29f536747f28c9672bec1cae7762d2c9f36b6013f2
. Dat is toevallig een collision met het woord geheim. Maar dat is niet het wachtwoord, het is het resultaat van het wachtwoord 1000x hashen. Als je dus een combinatie van een random salts, random aantal hash itteraties en een sterk wachtwoord wachtwoord vereist maak je het moeilijker om het wachtwoord te achterhalen (het kan altijd maar je probeert de benodigde tijd zoveel mogelijk te vergroten).

Overigens, als een hacker toegang heeft tot de database heeft heb je nog heel andere problemen, de rest van je data ligt ook op straat. Bij echt gevoelige data zou je moeten kijken naar database encryptie, auditing en access lists. Maar daar ken ik MySQL niet goed genoeg voor. Ik weet dat SQL Server 2008 daar een aantal goede mogelijkheden voor bied.

Acties:
  • 0 Henk 'm!

  • EdwinG
  • Registratie: Oktober 2002
  • Laatst online: 27-05 15:59
Voutloos schreef op zaterdag 29 januari 2011 @ 20:30:
Nou is een half uur ook nog niet echt schokkend, en dat toont meteen het grootste probleem als je alles technisch op orde hebt: Het gros van de gebruikers heeft een deprimerend slecht wachtwoord. :X
Gebruikers blijven inderdaad de zwakste schakel
Als je alles technisch op orde hebt, zullen je gebruikers geen 'koffie' of 'stoel' als wachtwoord hebben.
ok, waarschijnlijk zullen ze vervangen zijn door 'Koffie1!' en 'Stoel1!!', maar daar is helaas weinig aan te doen.

En een half uur lijkt misschien niet schokkend, maar als ik 500 wachtwoorden wil kraken ben ik daar toch zo'n tien dagen mee bezig, in plaats van de drie minuten zonder strengthening.
PolarBear schreef op zondag 30 januari 2011 @ 10:07:
Overigens, als een hacker toegang heeft tot de database heeft heb je nog heel andere problemen, de rest van je data ligt ook op straat. Bij echt gevoelige data zou je moeten kijken naar database encryptie, auditing en access lists. Maar daar ken ik MySQL niet goed genoeg voor. Ik weet dat SQL Server 2008 daar een aantal goede mogelijkheden voor bied.
Onder andere de functies AES_ENCRYPT() en AES_DECRYPT() kunnen gebruikt worden voor encryptie. Nadeel van deze functies is wel dat de encryptiesleutel in de query is opgenomen. Pas dus op met het loggen van eventuele foutmeldingen, aangezien de encryptiesleutel in de foutmelding terecht kan komen (en dus in het vaak onversleutelde logboek).

Een andere optie is natuurlijk het versleutelen van data voordat het in de query wordt geplaatst.


Terug naar de originale vraag, we raken een beetje off-topic.
Maaark schreef op donderdag 27 januari 2011 @ 20:48:
- Mis ik nog beveiligingsfunctie’s die echt niet mogen ontbreken?
Heb je al gedacht aan cross-site request forgery en clickjacking? De vraag is natuurlijk in hoeverre je dit type aanval als relevant beschouwt, maar het kan zeker geen kwaad om er over na te denken.

Een goede bron over beveiliging van websites is de OWASP Top 10 2010

Bezoek eens een willekeurige pagina


Acties:
  • 0 Henk 'm!

  • Kwastie
  • Registratie: April 2005
  • Laatst online: 23:22

Kwastie

Awesomeness

Het "idee" van een salt is dat iemand je (password)-hash kan "stelen" maar als hij niet de salt weet kan hij nooit het origineel achterhalen. Hij kan alleen een collision berekenen, maar dat is zinloos want je kunt deze collision niet gebruiken om bijv. in te loggen.

Ik durf dus te stellen dat MD5 net zo veilig kan zijn als bijv. SHA1 als je de salt key maar geheim kunt houden.

Zelf zou ik die gok niet nemen, want stel dat je salt-key word achterhaalt dan word het met md5 opeens heel makkelijk om de wachtwoorden te berekenen.

Wat ik zelf altijd probeer te doen is:
- salt-key van minimaal 256 bits
- aparte salt-key per hash
- salt-key en hash niet op dezelfde locatie opslaan

When I get sad i stop being sad and be awesome instead


Acties:
  • 0 Henk 'm!

Anoniem: 289377

Kwastie schreef op zondag 30 januari 2011 @ 17:53:
Het "idee" van een salt is dat iemand je (password)-hash kan "stelen" maar als hij niet de salt weet kan hij nooit het origineel achterhalen. Hij kan alleen een collision berekenen, maar dat is zinloos want je kunt deze collision niet gebruiken om bijv. in te loggen.

Ik durf dus te stellen dat MD5 net zo veilig kan zijn als bijv. SHA1 als je de salt key maar geheim kunt houden.

Zelf zou ik die gok niet nemen, want stel dat je salt-key word achterhaalt dan word het met md5 opeens heel makkelijk om de wachtwoorden te berekenen.

Wat ik zelf altijd probeer te doen is:
- salt-key van minimaal 256 bits
- aparte salt-key per hash
- salt-key en hash niet op dezelfde locatie opslaan
Nee het idee van salten is dat rainbow tables nutteloos worden. Je moet er gewoon altijd vanuit gaan dat je salts + hashes op straat liggen. Het is een webserver en daarmee bij voorbaat al verdacht. Verder is MD5 niet net zo veilig als SHA-1/2 vanwege het grote aantal aanvallen op MD5. Neem bijvoorbeeld het geldige SSL certificaat met een juiste MD5-fingerprint van de TU/e.

Acties:
  • 0 Henk 'm!

  • Kwastie
  • Registratie: April 2005
  • Laatst online: 23:22

Kwastie

Awesomeness

Anoniem: 289377 schreef op zondag 30 januari 2011 @ 19:39:
[...]

Nee het idee van salten is dat rainbow tables nutteloos worden. Je moet er gewoon altijd vanuit gaan dat je salts + hashes op straat liggen. Het is een webserver en daarmee bij voorbaat al verdacht. Verder is MD5 niet net zo veilig als SHA-1/2 vanwege het grote aantal aanvallen op MD5. Neem bijvoorbeeld het geldige SSL certificaat met een juiste MD5-fingerprint van de TU/e.
Wat ik wil zeggen is: Als je de salt-key geheim kunt houden is MD5 ook gewoon veilig, maar omdat je dat risico niet wilt nemen gebruik je een "sterker" algoritme, om ervoor te zorgen dat het berekenen van collisions langer duurt.

[ Voor 4% gewijzigd door Kwastie op 30-01-2011 19:56 ]

When I get sad i stop being sad and be awesome instead


Acties:
  • 0 Henk 'm!

  • ViNyL
  • Registratie: Augustus 2001
  • Niet online
Ik lees dit topic met grote belangstelling. Alleen veel ervan gaat (bijna) niet op voor het gene waar ik mee te maken heb op dit moment; de Active Directory.

Is er eigenlijk nog wat extra beveiliging voor een login op een Active Directory te doen vanuit een web applicatie? Je bent dan namelijk afhankelijk van hoe het wachtwoord in de AD opgeslagen is/wordt. Het werken met salts e.d. is dan niet mogelijk..

Een beveiligde verbinding is een ding en de AD blokkeert een account zelf na 5 foutieve inlogpogingen.

[ Voor 36% gewijzigd door ViNyL op 31-01-2011 10:32 ]


Acties:
  • 0 Henk 'm!

  • glrfndl
  • Registratie: Juni 1999
  • Niet online
Kwastie schreef op zondag 30 januari 2011 @ 19:54:
[...]


Wat ik wil zeggen is: Als je de salt-key geheim kunt houden is MD5 ook gewoon veilig, maar omdat je dat risico niet wilt nemen gebruik je een "sterker" algoritme, om ervoor te zorgen dat het berekenen van collisions langer duurt.
Dat is dus security through obscurity. De veiligheid van je systeem zou niet afhankelijk moeten zijn van het geheim houden van je algoritme (waar je salt bij hoort). Het kan dus een extra drempel zijn, maar het mag er niet van af hangen. Zie ook Wikipedia: Kerckhoffs's Principle

Wat MD5 betreft: niet gebruiken, period. Het is al tijden bekend dat het niet meer voldoet en er zijn prima alternatieven.

Prepare for unforeseen consequences


Acties:
  • 0 Henk 'm!

Anoniem: 146875

Even mijn login systeem, wat in mijn ervaring erg goed werkt.
1. Gebruiker ziet login scherm en voert gebruikersnaam + wachtwoord in
2. Als login succesvol is, zijn we hier klaar, anders stap 3
3. Als de login fout is dan volgt er een random delay tussen de 0.1 en 1.5 seconde
4. Maak een log in de database op welke tijd het laatst een foute login voor de gebruiker was. Geen IP log want veel aanvallen komen in mijn ervaring vanaf meerdere IP's tegelijk. Formaat:
datum: "woensdag 2 februari 15:32", gebruiker: "pietje" aantalFout: "2"
5. Opnieuw tonen van hetzelfde form met gebruikersnaam en wachtwoord
6. Als dit de poging X (staat nu op 5) of hoger is sinds de laatste foute login + Y (staat nu op 2) minuten, vereis dan een gebruikersnaam, wachtwoord, e-mail adres en een Captcha
7. Na 2 minuten geen enkele foute login poging voor pietje: reset naar stap 1

Voordelen:
- Bij geautomatiseerde pogingen een random delay, misschien van de webserver en misschien omdat het wachtwoord fout is
- Gebruiker pietje kan gewoon inloggen, als er toevallig op dat moment (maximaal 2 minuten geleden) iemand bezig is, dan moet hij wat extra velden invullen
- Niet mogelijk te achterhalen of een gebruiker bestaat. Ook voor niet bestaande gebruikers wordt een log gemaakt en zijn extra velden nodig
- Werkt ook bij aanvallen vanuit een zombie netwerk of bij meerdere proxies
- Accounts worden nooit geblokkeerd

Acties:
  • 0 Henk 'm!

  • EdwinG
  • Registratie: Oktober 2002
  • Laatst online: 27-05 15:59
Anoniem: 146875 schreef op woensdag 02 februari 2011 @ 15:51:
6. Als dit de poging X (staat nu op 5) of hoger is sinds de laatste foute login + Y (staat nu op 2) minuten, vereis dan een gebruikersnaam, wachtwoord, e-mail adres en een Captcha

"..."

Voordelen:
- Gebruiker pietje kan gewoon inloggen, als er toevallig op dat moment (maximaal 2 minuten geleden) iemand bezig is, dan moet hij wat extra velden invullen
Nadeel: Op het moment dat de captcha gekraakt is (wat met veel captcha's het geval is) kan de aanvaller ook blijven proberen. Eigenlijk heb je dus geen enkele time-out voor aanvallers die met de captcha overweg kunnen.

En waarom zou je niet op IP gaan blokkeren? Tenzij je tegenover een enorm botnet staat, kun je het aantal pogingen door ip-restricties aanzienlijk beperken. (Zeker als je de time-out op ip-adressen groter maakt dan de time-out op gebruikersnamen).

Zolang je niet op ip-adressen blokkeerd, kan ik als aanvaller, vanaf een enkele computer, eerst het wachtwoord 'wachtwoord' op alle (vermoedelijke) gebruikers proberen, vervolgens 'geheim', 'ditraadjenooit', 'koffie', 'stoel', etc... Omdat ik eerst alle gebruikersnamen probeer zit er een flinke tijd tussen twee pogingen op hetzelfde gebruikersaccount, en kom ik waarschijnlijk nooit een captcha tegen.

Aangezien gebruikers vaak eenvoudige wachtwoorden kiezen, krijg ik op die manier waarschijnlijk vrij snel een account te pakken. Alleen blokkade op ip-adres kan daar tegen helpen.

De beveiliging tegen username-enumeration is wel handig.

Bezoek eens een willekeurige pagina


Acties:
  • 0 Henk 'm!

Anoniem: 146875

@EdwinG: slim bedacht, dat is inderdaad een zwakke plek in het systeem.

Ik denk dat ik een stap 4a toevoeg, die iets doet als:
INSERT INTO tableIPAttempt (IPAddress, Attempts) VALUES ($ip, 1) ON DUPLICATE KEY UPDATE Attempts = Attempts + 1

In stap 5 kan ik dan kiezen of ik een extra delay + check toevoeg of het IP adres tijdelijk blokker, daar twijfel ik nog over.

Acties:
  • 0 Henk 'm!

  • keejoz
  • Registratie: November 2008
  • Laatst online: 06-04 13:29
Als er gebruteforced word dan wordt toch ook meestal een serieuze proxy-list gebruikt? Hoe los je dat dan op.

Acties:
  • 0 Henk 'm!

Anoniem: 146875

keejoz schreef op woensdag 02 februari 2011 @ 21:24:
Als er gebruteforced word dan wordt toch ook meestal een serieuze proxy-list gebruikt? Hoe los je dat dan op.
Combinatie van gebruikersnaam, wachtwoord, email en captcha verificatie in het geval van teveel attempts in X minuten (misschien is twee te laag) per user. Daarnaast IP's tijdelijk blocken die te veel foute pogingen doen.

Dan kun je zowel IP's als usernames moeilijker toegankelijk maken (of blocken)

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
keejoz schreef op woensdag 02 februari 2011 @ 21:24:
Als er gebruteforced word dan wordt toch ook meestal een serieuze proxy-list gebruikt? Hoe los je dat dan op.
Goede proxy lijsten zijn schaars (standaard proxy's sturen veelal ook het ip mee waarvoor ze proxyen). Botnets zijn wat dat betreft talrijker...

Echter kom je nu imho wel op een punt uit dat je je mag gaan afvragen, moet ik dit nu al tegenhouden, of kan de block nog even wachten.

Je kan nu nog meerdere kanten op, maar alle kanten hebben het risico dat ze ook mensen gaan blocken. Op dit niveau is een goed opgezet botnet niet meer 1-2-3 te herkennen van een mens.
- Je kan iets vernuftigs gaan verzinnen als responsetijden van de gebruiker meten ( maar dan block je de regulars die iets gewoon blind invullen/de keeppass of lastpass gebruikers en in het aller ergste geval heeft je spammer een vertraging in zijn spambot ingebouwd waardoor je die niet blokkeert maar wel andere gebruikers )
- Je kan via een ip-regio check landen / gebieden je site ontzeggen ( zeer twijfelachtig of je ook alle NL vakantiegangers jouw site wilt ontzeggen )
- Je kan .. je kan ...
maar dit zijn veelal allemaal technisch vernuftige dingen die een hele bak finetuning nodig hebben ( naast het bouwwerk ). Ik zou eerst eens kijken wat je site nu doet en aan de hand van die gegevens kan je dan een verdere methode gaan uitwerken.

Je houdt nu de 1e serie scriptkiddies tegen, een gerichte aanval moet je ook gericht stoppen. Dat gerichte stoppen kan je wel helemaal van te voren gaan bedenken en uitwerken, maar zonder ervaring met aanvallen ben je straks x maanden aan het programmeren eraan en dan blijk je maar 1000 hits op een dag te trekken.

Acties:
  • 0 Henk 'm!

  • Nijn
  • Registratie: Januari 2005
  • Laatst online: 08:13
Een aanval van een botnet of via een proxy lijst (al is dat dus minder waarschijnlijk) of simpelweg vrijwel alle aanvallen die gebruik maken van talloze IP's (denk even aan IPv6...) zullen vrijwel altijd het volgende gemeen hebben: Binnen een korte termijn komen er van een groot aantal IP's gelijkwaardige requests.

Dat is waar een goeie firewall z'n brood mee verdient. (Al dan niet bijgestaan door een admin welke in de statistieken duidelijk zal zien dat er iets aan de hand is en daar al lang een alarm van heeft gekregen)

Kortom, ik ben zelf van mening dat je een dergelijke (uitzonderlijke) aanval niet op dit niveau moet willen oplossen. Tenslotte, aanval methodes zullen blijven veranderen. Firewalls worden hierop geupdate. Echter, Je wilt niet bij iedere nieuwe aanval de software voor je Website moeten aanpassen.

Acties:
  • 0 Henk 'm!

  • Woet
  • Registratie: Mei 2006
  • Laatst online: 24-03 12:54
Over je wachtwoord encrypten, gebruik whirlpool met een salt die je door elkaar husselt.
PHP:
1
hash('whirlpool', $password)


Dus je maakt een whirlpool van het wachtwoord (128 random tekens), gooit daar nog eens 128 random tekens door heen en husselt deze door elkaar.

Over je sessions, als je gewoon een hash maakt met username + wachtwoord + IP adres en deze in een sessie opslaat, kan je dit altijd checken. Mocht iemand dan de cookies stelen gaat het alsnog niet lukken omdat het IP adres in de hash niet overeenkomt.


PHP:
1
$_SESSION['hash'] = hash('whirlpool', $user['username'].$user['password'].$_SERVER['REMOTE_ADDR']);


Over je random sleeps, doe gewoon een usleep in alle gevallen.
PHP:
1
usleep(mt_rand(0,9) * 1000);

De vertraging is niet merkbaar voor een bezoeker maar zorgt wel dat timing attacks niet werken.

En altijd dezelfde foutmeldinging (dus iets zoals 'Uw gebruikersnaam en/of wachtwoord zijn incorrect.')

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Nijn schreef op woensdag 02 februari 2011 @ 23:56:
Dat is waar een goeie firewall z'n brood mee verdient. (Al dan niet bijgestaan door een admin welke in de statistieken duidelijk zal zien dat er iets aan de hand is en daar al lang een alarm van heeft gekregen)
Een firewall die een volledig correct (maar ongewenst) bezoek gaat blokkeren, moet niet gekker worden...
Enige manier waarop dit zou kunnen gebeuren is door simpelweg ratelimiting toe te passen, er mogen niet meer dan xxx requests op index.htm tegelijk komen en of je daar echt vrolijk van wordt (elke scriptkiddie wordt door jou gelijk tot ddos gekroond, niemand kan meer op je site komen)
Tenslotte, aanval methodes zullen blijven veranderen. Firewalls worden hierop geupdate. Echter, Je wilt niet bij iedere nieuwe aanval de software voor je Website moeten aanpassen.
Firewalls worden niet geupdate om legitieme requests te stoppen.
Een brute-force botnet voert gewoon legitieme requests uit, enkel een beetje veel en een beetje snel en een beetje hoog foutpercentage.
Firewall kan enkel iets doen aan het beetje veel en beetje snel, maar dan creeert je firewall al snel een slashdot effect. Het foutpercentage dat kan enkel door je software bepaald worden.

Firewalls zijn heel handig voor openstaande poort, invalid requests, bekende hacks in grote apps(bij de duurdere varianten), bepaalde virus-sigs(bij de duurdere varianten) etc. etc. Maar ze kunnen niet magisch op een zelfgebrouwen php site zien wat een brute force hackpoging van een botnet is en wat niet.

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Woet schreef op donderdag 03 februari 2011 @ 00:18:
Over je sessions, als je gewoon een hash maakt met username + wachtwoord + IP adres en deze in een sessie opslaat, kan je dit altijd checken. Mocht iemand dan de cookies stelen gaat het alsnog niet lukken omdat het IP adres in de hash niet overeenkomt.
Ik weet niet of je ook internationale klanten wilt of klanten bij multinationals, zoja dan kan je dat ip-adres beter ietwat flexibel maken (of ip-pools in kunnen richten) want er zijn nog steeds grote bedrijven die meerdere gateways naar inet hebben waardoor het ip plotseling kan verspringen. Of je hebt mensen die met laptops werken en meerdere keren per dag van verschillende ips inloggen. Is zo lullig als je daardoor iemand uitlogt.

Daarom hebben ze op meerdere sites (ik dacht ook t.net) de mogelijkheid tot ip-fixeren, maar is het niet verplicht.
Alternatieve mogelijkheid is om ip + browsergegevens (versie etc) op te slaan en dan te zeggen dat of het ip gelijk moet zijn of de browsergegevens, 1 van de 2 mag dan wijzigen zonder uit te loggen.
Dan heb je nog wel een paar random uitlogs doordat mensen hun browserversie eerst bijwerken op een nieuwe locatie en daarna pas op jouw site gaan. Maarja, je kan niet alles hebben.

Acties:
  • 0 Henk 'm!

  • EdwinG
  • Registratie: Oktober 2002
  • Laatst online: 27-05 15:59
Nijn schreef op woensdag 02 februari 2011 @ 23:56:
Een aanval van een botnet of via een proxy lijst (al is dat dus minder waarschijnlijk) of simpelweg vrijwel alle aanvallen die gebruik maken van talloze IP's (denk even aan IPv6...) zullen vrijwel altijd het volgende gemeen hebben: Binnen een korte termijn komen er van een groot aantal IP's gelijkwaardige requests.
Voor IPv6: Blokkeer blokken. Bijvoorbeeld bij X (10) geblokkeerde adressen in een /64 het hele blok uitschakelen. Bij 2*X in een /56 hetzelfde, bij 4*X een /48, bij 8*X een /40. Gezien het standaard netmask van IPv6 is een /64 eigenlijk één enkele internetverbinding, en moet dan (in zekere mate) ook zo behandeld worden. Verder zijn IPv6 blokken (als ik het goed begrijp) redelijk geografisch gerangschikt, waardoor het moeilijk wordt om IPv6 blokken die ver uit elkaar liggen te verkrijgen, en het blokkeren van groter blokken dus effectief wordt.

Let wel, ik heb geen uitgebreide IPv6-studie gevolgd :P

Bezoek eens een willekeurige pagina


Acties:
  • 0 Henk 'm!

  • trinite_t
  • Registratie: Maart 2003
  • Laatst online: 28-05 15:03
Zitten jullie nu niet aan puur symptoom bestrijding te doen? Als het echt om data gaat die heel erg veilig moet zijn, dan zijn (alleen) wachtwoorden sowieso niet de goede manier. Gebruikers geven deze veel te makkelijk aan anderen door/gebruiken te vaak dezelfde wachtwoorden.

Meestal heb je van gebruikers ook een e-mail of telefoon nummer. Blokkeer na 3 foute logins gewoon het account en stuur een mail of sms naar de gebruiker met een heractivatie link/code. Dan heb je direct het probleem van bruteforcen opgelost.

Als je het nog veiliger wilt doen ga je voor iedere login een mail/sms naar de gebruiker sturen met een inlog code.

En fuck die random timeouts, dat is echt alleen maar symptoom bestrijding.

The easiest way to solve a problem is just to solve it.


Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Woet schreef op donderdag 03 februari 2011 @ 00:18:
Over je wachtwoord encrypten, gebruik whirlpool met een salt die je door elkaar husselt.
PHP:
1
hash('whirlpool', $password)
Whirlpool is een hash-algoritme, heeft niks met encryptie te maken, de naam van je functie geeft t al aan ook ;)
Dus je maakt een whirlpool van het wachtwoord (128 random tekens), gooit daar nog eens 128 random tekens door heen en husselt deze door elkaar.
Wachtwoord van 128 karakters? Ik mis een stapje denk ik...
Over je sessions, als je gewoon een hash maakt met username + wachtwoord + IP adres en deze in een sessie opslaat, kan je dit altijd checken. Mocht iemand dan de cookies stelen gaat het alsnog niet lukken omdat het IP adres in de hash niet overeenkomt.
Een random token volstaat , zet ook een cookie met het userid en je krijgt een combo die je niet kunt verzinnen. IP check hier zou ik nooit doen, als iemand een dynamisch ip heeft dan kan ie nooit ingelogd blijven. Maak de IP-check optioneel en controleeer dat serverside.

Acties:
  • 0 Henk 'm!

Anoniem: 146875

trinite_t schreef op donderdag 03 februari 2011 @ 09:15:
Zitten jullie nu niet aan puur symptoom bestrijding te doen? Als het echt om data gaat die heel erg veilig moet zijn, dan zijn (alleen) wachtwoorden sowieso niet de goede manier. Gebruikers geven deze veel te makkelijk aan anderen door/gebruiken te vaak dezelfde wachtwoorden.

Meestal heb je van gebruikers ook een e-mail of telefoon nummer. Blokkeer na 3 foute logins gewoon het account en stuur een mail of sms naar de gebruiker met een heractivatie link/code. Dan heb je direct het probleem van bruteforcen opgelost.

Als je het nog veiliger wilt doen ga je voor iedere login een mail/sms naar de gebruiker sturen met een inlog code.

En fuck die random timeouts, dat is echt alleen maar symptoom bestrijding.
Daarmee kun je mensen geheel blokkeren, ik doe als aanvaller continue een login poging met username trinite_t waardoor jou account geblocked wordt. Vervolgens klik jij op de link in je mail maar omdat ik doorblijf gaan met aanvallen zijn er binnen een seconde alweer 3 nieuwe foute login pogingen geweest van mij waardoor jij nooit meer kan inloggen.

Acties:
  • 0 Henk 'm!

  • posttoast
  • Registratie: April 2000
  • Laatst online: 23:30
skabouter schreef op zaterdag 29 januari 2011 @ 13:47:

Waarom moet je dit ook voor gelukte login's toepassen? Wat je moet doen is het koppelen aan de IP van de "bezoeker". Stel ik log in op site x en het gaat goed >> geen delay, stel hacker Y probeert in te loggen en dit mislukt steeds >> steeds sleep(($poging_nr * $poging_nr ) * 2 ms) voor het gebruikte IP. Hiermee vertraag je het aantal pogingen per gebruikt IP.
Late reactie, maar ik lees dit nu pas. Waarom koppelen aan IP en niet gewoon in de sessie zetten? Dus wanneer de login incorrect is het volgende uitvoeren:
PHP:
1
2
3
4
5
6
7
if (!isset($_SESSION['admin']['login_attempt'])){
  $_SESSION['admin']['login_attempt'] = 0;
}
$_SESSION['admin']['login_attempt']++;
$delay = $_SESSION['admin']['login_attempt'] * $_SESSION['admin']['login_attempt'] * 2 * 1000;
usleep($delay);
$output['errors'] = 'Gebruikersnaam en/of wachtwoord zijn onjuist';

Dat scheelt weer een extra databasequery toch? Of is dit minder veilig?

omniscale.nl


Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
posttoast schreef op zaterdag 12 februari 2011 @ 22:29:
[...]

Late reactie, maar ik lees dit nu pas. Waarom koppelen aan IP en niet gewoon in de sessie zetten?
Sessies zijn makkelijker weg te gooien als ip's. Oftewel sessie-locks bieden helemaal niets... Je gooit je cookies weg en je hebt een nieuwe sessie

Acties:
  • 0 Henk 'm!

Anoniem: 146875

Probleem met sessies is dat je in de code verwacht dat de client ze meestuurt. Als je dat niet doet zal login_attempt altijd 0 blijven. Als je geen cookie (of sessie in de querystring) meestuurt naar de webserver dan ben je wat de webserver betreft gewoon een nieuwe gebruiker

Acties:
  • 0 Henk 'm!

  • posttoast
  • Registratie: April 2000
  • Laatst online: 23:30
Helder :) Ik heb het inmiddels netjes in een DB-tabel gezet, op IP-adres.

omniscale.nl

Pagina: 1