Beschermen tegen injections
Je kan ook gewoon het IP voor 5 minuten in de iptables van Linux gooien en nullrouten.
Dus ik zou niet inzien waarom mijn gestelde brute-force beveilging niet handig is? Je denkt gewoon te ver door naar doem-scenario's ;-).
Goed, je kunt SQL injection voorkomen door een hele community je code te laten auditten maar dit kun je zelf alleen voorkomen door anders naar code te gaan kijken. Specifiek door te letten op alle data die van buitenaf komt, ook wel user data (of user input) genoemd. Het komt eigenlijk op het volgende neer:
Do Not Trust User Data
Het is een vergissing om te denken dat user data alleen voorkomt in $_GET en $_POST enzo. Nadat user data in de database is opgeslagen is dit nog steeds user data en is deze nog steeds potentieel gevaarlijk.
Vervolgens moet je je afvragen: wat maakt een website onveilig. Simpel antwoord: alles wat de normale werking van een website kan manipuleren of breken. User data kan daar een groot aandeel in spelen, immers, je kunt daarmee data invoeren die in een bepaalde context een bepaalde betekenis heeft. En daarmee raak je precies de kern van de zaak: het is jouw taak als programmeur om deze data te ontdoen van haar speciale betekenis binnen die bepaalde context.
En dit doe je weer met escaping-functies voor de bijbehorende context: real_escape_string() (in combinatie met quotes, het een is niet veilig zonder het ander) voor de DATA-delen in je SQL, htmlspecialchars() voor alles wat je in (een) HTML(-document) doet, urlenocde() voor querystring-parameters in URLs et cetera. Ook zou je invoer aan syntactische controles moeten onderwerpen nog voordat je deze ergens gaat gebruiken. Kort samengevat:
Filter Input, Escape Output
Bij elk stukje data moet je je afvragen: WAAR komt dit vandaan en HOE behandel ik deze. Pas als je dit en de bovenstaande principes ALTIJD en OVERAL toepast heb je enige garantie dat je code redelijk veilig kan omgaan met user data...
... behalve nog het volgende. Escaping-functionaliteit is afhankelijk van character encoderingen. Deze werkt alleen goed indien de character encoding van de data die je escaped overeenstemt met de character encoding die je hanteert bij het escapen.
Bij het maken van je database connectie selecteer je nergens een character encoding (middels set_charset()), dus grote kans dat deze latin1 is. En zelfs al is deze toevallig utf8, dan nog zou je deze expliciet in moeten stellen. Ook grote kans dat er op dit moment dubbel utf8 ge-encodeerde data in je database zit (als je tabellen utf8 zijn) omdat MySQL de vertaling latin1 -> utf8 automatisch voor jou probeert uit te voeren. Wees altijd expliciet met het opgeven van character encoderingen of andere cruciale instellingen, neem hierbij niets aan. No zo eentje voor aan de muur:
Assume Nothing
Overigens: als jij het filter-input-escape-output principe goed zou toepassen zouden dus ook alle $_SERVER en $_CONFIG directives (en wat nog meer) in je HTML-document ge-escaped moeten worden.
Oh, en na een header('Location: ...') hoort altijd een exit te staan, anders is je code mogelijk onveilig.
En zo kan ik nog wel even doorgaan. Je hebt dit niet in een dag onder de knie, simpelweg omdat je (nog) niet weet wat er allemaal speelt of wat van invloed kan zijn.
Een maintenance mode zou ik niet af laten hangen van je database. Maak een config-var aan die aangeeft of de site toegankelijk is (site_online) ofzo en maak een whitelist met developer IP's. Controleer allereerst of de site online is en/of het IP voorkomt in een whitelist, serveer anders een statisch document middels een include.
Gewijzigd op 05/12/2016 16:15:29 door Thomas van den Heuvel
Thomas van den Heuvel op 05/12/2016 15:32:26:
Zucht, hier gaan we weer.
Als je er zo moe van wordt. Waarom maak je dan niet een tutorial hier op PHPhulp aan en verwijs je daarnaar toe? Zomaar een ideetje. ;-)
Gewijzigd op 05/12/2016 15:50:01 door - Ariën -
- Ariën - op 05/12/2016 15:49:38:
Als je er zo moe van wordt. Waarom maak je dan niet een tutorial hier op PHPhulp aan en verwijs je daarnaar toe? Zomaar een ideetje. ;-)
Ik kan net zo goed naar een post wijzen als naar een tutorial. Enne, ik dacht dat het doen van herhalingen van zetten hier ingeburgerd was (zoals het oproepen tot het aanzetten + weergeven van foutmeldingen).
Waarom zou ik nog meer moeite spenderen aan het maken een tutorial? In beide gevallen is het water naar de zee dragen.
Je zou zelfs een soort van beslisboom kunnen maken voor eenieder die hier een vraagstuk plaatst. Grote kans dat een groot deel dan meteen opgelost is.
Zoiets dus:
Gewijzigd op 05/12/2016 16:02:06 door Thomas van den Heuvel
Zullen we weer terug naar het onderwerp gaan?
Rob Chesture op 05/12/2016 14:40:22:
Daar check ik of de gebruiker ingelogd is. als dat niet zo is wordt hij/zij teruggestuurd.
Toevoeging op 05/12/2016 15:24:46:
Is niet al te handig, hiermee wordt elke keer als je page reload de query uitgevoerd. Dus als ze dan ook nog page_reload in brute_force zetten, kan de server nog steeds overbelast worden.
Ivo P op 05/12/2016 09:55:29:
ik mis nog de inhoud van het script waar je op komt na header('Location: /dashboard')
Check je daar ook of de gebruiker ingelogd is? (en zo nee, stuur je hem dan terug naar het inlogscript).
en op regel 12 en 15 van je inlogfunctie voer je dezelfde query uit.
Op regel 13 zit het id dus in $result['id']
beetje zinloos om dat nog een keer uit te voeren om in $id['id'] dezelfde waarde te stoppen.
Check je daar ook of de gebruiker ingelogd is? (en zo nee, stuur je hem dan terug naar het inlogscript).
en op regel 12 en 15 van je inlogfunctie voer je dezelfde query uit.
Op regel 13 zit het id dus in $result['id']
beetje zinloos om dat nog een keer uit te voeren om in $id['id'] dezelfde waarde te stoppen.
Daar check ik of de gebruiker ingelogd is. als dat niet zo is wordt hij/zij teruggestuurd.
Toevoeging op 05/12/2016 15:24:46:
Quote:
Bij elke foutieve inlog sla je het IP op, de userID van het account en het aantal keer dat er geprobeerd is. Als dat gelijk of hoger is dan 5 bijvoorbeeld, dan blokkeer je het account op dat IP.
Is niet al te handig, hiermee wordt elke keer als je page reload de query uitgevoerd. Dus als ze dan ook nog page_reload in brute_force zetten, kan de server nog steeds overbelast worden.
Nog enige andere ideeën?
https://www.owasp.org/index.php/PHP_Security_Cheat_Sheet
Probeer eerst maar eens je script uit te bouwen.
Als je 2 Factor Authentication wilt wilt inbouwen:
https://github.com/PHPGangsta/GoogleAuthenticator
Als ik mij niet vergis is het iets als:
Code (php)
Gewijzigd op 05/12/2016 17:07:18 door - Ariën -
Edit:
Het is niet nodig om het vorige bericht te quoten.
Gewijzigd op 05/12/2016 19:44:25 door - Ariën -
Daarom moet je eerst alle data ophalen met de genoemde parse_ini_file() functie. Dan mis je geen data.