login  Naam:   Wachtwoord: 
Registreer je!
 Forum

Tips gevraagd m.b.t. beveiliging loginscript. (Opgelost)

Offline Wykser - 09/03/2008 16:19
Avatar van WykserNieuw lid Ik had graag wat tips, in de zin van waar ik op moet letten qua beveiliging als ik een login script ga maken.
Ik heb verschillende scripts bekeken, maar vaak kan ik al aan de user comments zien dat het niet veel soeps is en dat het onveilig is. Ik wil bij m'n script gebruik gaan maken van een MySQL tabel en Sessies.

Hopelijk heeft iemand zin/tijd om even wat op een rijtje te zetten...

Mvg,
Wykser.

22 antwoorden

Gesponsorde links
Offline Martijn - 09/03/2008 16:55
Avatar van Martijn Crew PHP naja, je moet zorgen dat je $POST data word beveiligt met addslashes ed.....
verder kan ik je niet echt helpen, ben bang dat ik 1 van SiMa heb verbouwd tot mn eigen gedoe 8-)
Offline Grayen - 09/03/2008 18:15
Avatar van Grayen PHP ver gevorderde * Zoals DeviourSoul al zei, is het belangrijk om alle variables die je binnen je query zal gaan gebruiken te coderen. Zie hier voor informatie waarom en waarop je moet letten: http://www.weba...1007.shtml
* Geef niet aan welke van de twee inloggegevens fout zijn (wachtwoord of gebruikersnaam) hiermee help je alleen de hacker mee. Je moet gewoon iets van "De inloggegevens zijn incorrect" weergeven.
* Zorg ervoor dat iemand maar iets van 3-5 keer achter elkaar de inloggegevens fout mag hebben. Als dat limiet bereikt is laat de persoon dan enkele minuten wachten voordat hij weer mag proberen in te loggen.
* Vertraag je inlogscript met enkele seconden als hij fout is, zodat als er een hacker script wordt gebruikt deze erg lang zal duren.
* Maak in je formulier een hiddenveld met een random waarde. Deze waarde moet gelijk zijn aan een sessie. Als iemand dan inlogd moet er worden gecontroleerd of deze waardes nog wel hetzelfde zijn. Op die manier kan niemand het formulier extern uitvoeren. Je moet dus echt op de pagina zelf zitten wil je kunnen inloggen. Lees deze pagina voor meer informatie hierover: http://phpsec.org/projects/guide/2.html
* Hash altijd de wachtwoorden die in de database staan, dat is veiliger en eigenlijk een soort regel, omdat je anders de wachtwoorden van alle gebruikers kan lezen.
* Als je bij het regristeren bepaalde regels hebt gesteld aan username/password zoals alleen a-z0-9 voer dat dan in het inlogscript ook uit, is kans op sql injection kleiner.

En dat waren ze wel zo beetje die ik me zo herriner.
Offline Wykser - 09/03/2008 21:16
Avatar van Wykser Nieuw lid Bedankt Grayen. 
Ik had idd al een aantal van deze dingen gevonden, maar het is mooi om ze allemaal op een rij te hebben.
Offline Threetimes - 09/03/2008 21:46 (laatste wijziging 09/03/2008 21:47)
Avatar van Threetimes PHP beginner
Grayen schreef:
Als je bij het regristeren bepaalde regels hebt gesteld aan username/password zoals alleen a-z0-9 voer dat dan in het inlogscript ook uit, is kans op sql injection kleiner.
Liever niet, wachtwoorden met tekens als !@#$%^&* enzo zijn veiliger.
Wat wel kan is alleen `"'<> en spaties blokkeren, dan kan je geen code of queries schrijven.
Offline Grayen - 09/03/2008 21:50
Avatar van Grayen PHP ver gevorderde Het was dan ook maar een voorbeeld (zie woordje "zoals") . Maar inderdaad bij wachtwoorden is het veiliger als je meerdere tekens toe laat.
Offline KWebServices - 09/03/2008 22:38
Avatar van KWebServices Nieuw lid Maak bij elke query gebruik van mysql_real_escape_string(), hierdoor wordt 't (bijna) onmogelijk om SQL-injection uit te voeren. Het werkt tevens efficienter dan de addslashes() + htmlentities() combinatie...

Een voorbeeld hiervan:

  1. mysql_query("SELECT * FROM `users` WHERE
  2. `user` = '" . mysql_real_escape_string($_POST['user']) . "' AND
  3. `pass` = '" . md5($_POST['pass']) . "'
  4. LIMIT 1";


Bij het wachtwoord is dit niet per se nodig, gezien deze al meteen in een md5-hash wordt gegooit.
Offline nemesiskoen - 09/03/2008 22:51 (laatste wijziging 09/03/2008 22:53)
Avatar van nemesiskoen Gouden medaille

PHP expert
Citaat:
Maak bij elke query gebruik van mysql_real_escape_string(), hierdoor wordt 't (bijna) onmogelijk om SQL-injection uit te voeren. Het werkt tevens efficienter dan de addslashes() + htmlentities() combinatie...

Geef me eens een goede reden waarom mysql_real_escape_string efficienter zou zijn voor sql-injection tegen te gaan dan addslashes?

Er is ook no point in het gebruik van mysql_real_escape_string ipv mysql_escape_string in jouw voorbeeld. Want in jouw voorbeeld is het resultaat IDENTIEK.
Offline KWebServices - 09/03/2008 23:34 (laatste wijziging 09/03/2008 23:34)
Avatar van KWebServices Nieuw lid mysql_real_escape_string() is efficienter in geheugengebruik en sneller vergeleken het htmlentities()- en addslashes-duo...

Wat betreft mysql_escape_string():
Citaat:
Note: mysql_escape_string() escapet % en _ niet. Deze functie is identiek aan mysql_real_escape_string() behalve dat mysql_real_escape_string() een connectie handler als argument neemt en de string escaped volgens de huidige tekenset. mysql_escape_string() neemt geen connectie handler argument en negeert de tekenset instelling.

Bron: http://nl2.php.net/mysql_escape_string
Offline nemesiskoen - 09/03/2008 23:52 (laatste wijziging 10/03/2008 00:00)
Avatar van nemesiskoen Gouden medaille

PHP expert
Euhm... ik weet denk ik net iets beter als jij wat het verschil tussen mysql_escape_string en de real versie. Zoek nog eens op op die toffe php.net site en dan kom je er wel achter dat in jouw voorbeeld je beter mysql_escape_string had gebruikt omdat je geen gebruik maakt van een resource. Verder zijn ze identiek, de real versie escaped _% ook niet:-)

addslashes en mysql_escape_string vergelijken is appels met appels vergelijken
htmlentities en mysql_escape_string vergelijken is appels met peren

De twee functies doen iets heel anders. Als je javascript invult zal mysql_escape_string dit gewoon laten staan als javascript. Dus je zal er zowiezo htmlenities moeten overzwieren, als het nu bij op de input of de output is, dat mag jij zelf kiezen.
Wat jij je moet afvragen is of "mysql_real_escape_string en htmlentities" efficienter in geheugengebruik is dan "addslashes en htmlentities". Het antwoord daarop is eenvoudig: de tweede, heel eenvoudig om addslashes enkele zaken niet escaped: ASCII 9, 10, 26 (\n, \r en -> (aan elkaar)), (en nog een paar andere idiote zaken)

Dus als jij alleen maar mysql_escape_string gebruikt is jouw code niet echt veilig...
Offline ranco - 10/03/2008 00:24
Avatar van ranco PHP gevorderde
vage schreef:
Euhm... ik weet denk ik net iets beter als jij wat het verschil tussen mysql_escape_string en de real versie.


Gevalletje eigen dunk?

bah, doe niet zo uit de hoogte, we proberen elkaar alleen maar te helpen hoor!
Offline nemesiskoen - 10/03/2008 00:51 (laatste wijziging 10/03/2008 00:52)
Avatar van nemesiskoen Gouden medaille

PHP expert
Citaat:
Gevalletje eigen dunk?

Als hij als antwoord op een simpel statement een link geeft naar een pagina die mijn antwoord bevestigd vraag ik me af of hij er al iets van begrijpt.

Natuurlijk helpen we elkaar allemaal maar hij maakt de topicposter z'n site onveilig. Het zou idioot van mezelf zijn daar geen commentaar op te geven.
Offline Abbas - 10/03/2008 01:42
Avatar van Abbas Gouden medaille

Crew .NET
Citaat:
Gevalletje eigen dunk?
bah, doe niet zo uit de hoogte, we proberen elkaar alleen maar te helpen hoor!
Hetgeen hij doet is juist helpen!!! En eigendunk, nee hoor! vage weet waarover hij spreekt, als je hem kende gaf je hem gelijk! 
Offline Grayen - 10/03/2008 08:04
Avatar van Grayen PHP ver gevorderde @titjes
Dus pas als ik vage ken, dan pas zou ik hem gelijk geven? :S. Is het niet eerder logisch (in dit geval) dat je eerder kijkt naar zijn argumenten.

Citaat:
Geef me eens een goede reden waarom mysql_real_escape_string efficienter zou zijn voor sql-injection tegen te gaan dan addslashes?


Alstu: http://shiflett...ape-string

Citaat:
Zoek nog eens op op die toffe php.net site en dan kom je er wel achter dat in jouw voorbeeld je beter mysql_escape_string had gebruikt omdat je geen gebruik maakt van een resource. Verder zijn ze identiek


Als jij dat nou eens deed:

Citaat:
The MySQL connection. If the link identifier is not specified, the last link opened by mysql_connect() is assumed. If no such link is found, it will try to create one as if mysql_connect() was called with no arguments. If by chance no connection is found or established, an E_WARNING level warning is generated.


Het is nogal logisch dat voordat hij mysql_query aanroept een mysql connectie opent .

Wat betreft htmlentities, daar is hier geen sprake van, want ik mag aannemen dat zaak is bij het regristeren (het filteren van bepaalde tekens) en niet bij het inloggen.

Dus in dit geval: Gebruik gewoon mysql_real_escape_string(). Die functie is niet voor niets uitgebracht, omdat PHP de fout heeft gemaakt om enkele gevaarlijke zaken niet te encoderen bij mysql_escape_string en daarom hebben ze de _real groep toegevoegd waarin deze wel geencodeerd worden.
Offline nemesiskoen - 10/03/2008 10:37 (laatste wijziging 10/03/2008 10:40)
Avatar van nemesiskoen Gouden medaille

PHP expert
Citaat:
Het is nogal logisch dat voordat hij mysql_query aanroept een mysql connectie opent .

Agree, maar wat ik wel veel zie is dat mysql_real_escape_string voor een query wordt gebruikt (en dan opslaan in variabelen). En daarbij vind ik het niet logisch dat de verbinding openstaat. Het is niet omdat bijna elk php-script dit heeft dat het daarom normaal is. Ik werkte idd vroeger ook zo, maar what's the point in je connectie heel de tijd hebben openstaan als je maar 1 query moet doen? Dan is het veel logischer dat je volgende opstelling volgt:
- code
- open connectie
- query
- sluit connectie
- rest code

Als ik bezoek verwacht dan zet ik mijn deur niet open en laat ik het bezoek binnenkomen zoveel als het wil. Neen, gelijk elke normale mens wacht ik tot er iemand aanbeld en dan open ik de deur (open connectie) laat ik de mensen binnen (query de informatie) en sluit ik de deur (sluit connectie).

Waar je wel gelijk in hebt is dat (hoewel ik het tegendeel beweerde) in zijn geval er geen verschil is. Goed, hij voert hem uit in een query, dus de link wordt wel meegegeven. Maar er zal pas verschil zijn als de charset verschild van de gewone (wat in 99% van de gevallen niet is).

Kan je mij een lijstje geven met zaken die _real wel codeerd en de gewone niet (zonder de charset aan te passen). Het is trouwens ook veel trager omdat het de charset moet vergelijken.

Ik vraag me af (en dan echt honestly) wat er kwaad kan gebeuren als je enkel ' en " escaped. Het kan goed zijn dat er dan vanalle rotzooi kan gebeuren maar kan je hier eens een concreet voorbeeld van geven?
Offline Grayen - 10/03/2008 13:33
Avatar van Grayen PHP ver gevorderde
Citaat:
Waar je wel gelijk in hebt is dat (hoewel ik het tegendeel beweerde) in zijn geval er geen verschil is. Goed, hij voert hem uit in een query, dus de link wordt wel meegegeven. Maar er zal pas verschil zijn als de charset verschild van de gewone (wat in 99% van de gevallen niet is).

Klopt, maar ik gebruik liever de regel: "Alle input is slecht, dus van het slechtste uitgaan".

Citaat:
Kan je mij een lijstje geven met zaken die _real wel codeerd en de gewone niet (zonder de charset aan te passen). Het is trouwens ook veel trager omdat het de charset moet vergelijken.


Oftewijl geen verschil (zonder de charset aan te passen).

Dat kun je op php.net vinden bij mysql_escape_string:

Citaat:
This function is identical to mysql_real_escape_string() except that mysql_real_escape_string() takes a connection handler and escapes the string according to the current character set. mysql_escape_string() does not take a connection argument and does not respect the current charset setting.


Addslashes is waarschijnlijk in meer als 90% van de gevallen voldoende. Maar ik ga liever van het ergste geval uit (een bepaalde charset in combinatie met input die geen controle hebben) dan zou addslashes tekort schieten, maar die kans dat het voorkomt is inderdaad miniem. Dus conclusie:

Addslashes is in bijna alle gevallen voldoende en sneller.
mysql_real_escape_string is iets veiliger, maar langzamer.

Dus het is een persoonlijke keuze. Je moet beide voor en nadelen omwegen en kijken wat voor jouw het beste is.

Ik heb nog wel een extra tip, plaats om elke waarde quotes ook al heb je te maken met een integer waarbij het niet hoeft, toch doen, want zoals je in mijn eerste reactie kon lezen bij de eerste link die ik gaf, is addslashes/mysql_real_escape_string niet altijd voldoende.
Offline nemesiskoen - 10/03/2008 14:01 (laatste wijziging 10/03/2008 14:02)
Avatar van nemesiskoen Gouden medaille

PHP expert
Citaat:
Dus het is een persoonlijke keuze. Je moet beide voor en nadelen omwegen en kijken wat voor jouw het beste is.

'k denk dat het eerder afhangt van "fiets gebruiken om te fietsen en vliegtuig gebruiken om te vliegen"... als je begrijpt wat ik bedoel. Per variabele afgaan wat er mogelijk zou kunnen zijn.

Citaat:
Dat kun je op php.net vinden bij mysql_escape_string:

De site ken ik wel:-)

Citaat:
Ik heb nog wel een extra tip, plaats om elke waarde quotes ook al heb je te maken met een integer waarbij het niet hoef

Euhm... casting? "INSERT ... VALUES (". (int)$je_getal . ")"
integers zijn echt te easy om te beveiligen.
Offline Grayen - 10/03/2008 15:15
Avatar van Grayen PHP ver gevorderde
Citaat:
Euhm... casting? "INSERT ... VALUES (". (int)$je_getal . ")"
integers zijn echt te easy om te beveiligen.

Dat is waar, maar bijvoorbeeld is_numeric is alweer onveilig. Dus ik plaats gewoon altijd quotes om integers heen voor het geval dat ik een enkele keer vergeet te casten en bijv een functie als is_numeric gebruik.
Offline KWebServices - 10/03/2008 19:02 (laatste wijziging 10/03/2008 19:03)
Avatar van KWebServices Nieuw lid
Citaat:
Er is ook no point in het gebruik van mysql_real_escape_string ipv mysql_escape_string in jouw voorbeeld. Want in jouw voorbeeld is het resultaat IDENTIEK.

Waarom dan al het gemuggenzift? Ik gebruik altijd mysql_real_escape_string(), dit is mijn advies. Een advies wat tevens goed te gebruiken is en uiteindelijk Wykser goed zal helpen met z'n script...
if(!agree()) print $this->me . " doesn't freakin' care!";
Offline timmie_loots - 31/08/2008 23:09
Avatar van timmie_loots PHP gevorderde
Grayen schreef:
[..quote..]
Dat is waar, maar bijvoorbeeld is_numeric is alweer onveilig. Dus ik plaats gewoon altijd quotes om integers heen voor het geval dat ik een enkele keer vergeet te casten en bijv een functie als is_numeric gebruik.


Ik vind het zeer apart dat je je aan de ene kant om vrij nutteloze optimalisaties druk kan maken, maar aan de andere kant practices hanteert die juist trager zijn.

Gewoon, zoals vage zegt, naar een integer casten is altijd veilig. Dat er andere oplossingen zijn doet daar niets aan af, ook het argument 'ik kan het vergeten' niet. Als je op die manier gaat programmeren dan blijf je bezig.

Gewoon mysql_real_escape_string() gebruiken is het beste. Gebleken is dat die gewoon het veiligste is, en om het zogenaamde prestatieverlies hoef je het écht niet te laten.

Offline Abbas - 31/08/2008 23:17
Avatar van Abbas Gouden medaille

Crew .NET
Waarom reageren op een topic van een half jaar geleden?! ^^
Offline vinTage - 01/09/2008 00:03
Avatar van vinTage Nieuw lid
titjes schreef:
Waarom reageren op een topic van een half jaar geleden?! ^^


Was niet gesloten, dus waarom geen nuttige toevoeging ? 

Offline timmie_loots - 01/09/2008 14:29 (laatste wijziging 01/09/2008 14:31)
Avatar van timmie_loots PHP gevorderde
titjes schreef:
Waarom reageren op een topic van een half jaar geleden?! ^^


Ehh.. 8)7

Was er op gekomen via Veilig login systeem, maar stond al een tijdje open in een tab. Toen vergeten dat het zo oud was, dacht op het moment van posten dat hij gewoon uit de actieve topics kwam.

Ach, mijn punt blijft, toentertijd zijn er wat opmerkingen gemaakt waarop ik wilde reageren. Misschien ooit nog handig, misschien zelfs voor het topic waarin het is aangehaald.
Gesponsorde links
Dit onderwerp is gesloten.
Actieve forumberichten
© 2002-2024 Sitemasters.be - Regels - Laadtijd: 0.26s