Website beveiligen PDO

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Website beveiligen PDO

      Beste,

      Ik ben sinds kort weer bezig met scripten. En ben aan het leren om PDO te scripten...

      Enkel heb ik kleine vraagjes:
      Op wat moet ik allemaal letten kwa website beveiligen
      IK maak gebruik van OOP PDO.. Dus neem aan dat sql injection niet meer mogelijk is...

      En wat kan ik doen aan :
      catch(PDOException $e){ echo $e->getMessage();}Ik wil graag dat de logs opgeslagen worden en dat er geen error code komt maar wat vriendelijke tekst..Moet ik dat elke x bij de pdoexception zetten of kan ik ook een eigen PDO exceptions class makenMet vriendelijke groet
      Ik sta open voor projecten.
      Ik sta ook tehuur als scripter
      PM voor meer informatie
    • MBCompany wrote:

      Dus neem aan dat sql injection niet meer mogelijk is...
      Dat is een misverstand, daarnaast, er vanuitgaan dat je "veilig bent" is het do... onveiligste wat je kunt doen.

      PDO maakt gebruik van prepared statements. Dit houdt in dat je de variabele DATA-delen in een query indirect invoegt via de bindParam() of bindValue() methoden, of meegeeft als argument van je execute() statement.

      Als je dit omzeilt door rechtstreeks data in te voegen in je SQL-string (denk bijvoorbeeld -maar niet uitsluitend- aan data afkomstig uit $_POST of $_GET) dan omzeil je daarmee de spelregels van prepared statements en is het nog steeds zeer goed mogelijk dat er SQL injectie plaatsvindt.

      Soms is het bovenstaande (het niet via bindParam() / bindValue() / execute invoegen van DATA) noodzakelijk, omdat er geen andere manier voor is. Dan is het zaak dat je je invoer controleert op toegestane waarden (je vergelijkt dit dus met een "whitelist").

      Verder is het zaak dat je character encoderingen op orde zijn. Je output (HTML pagina), je broncode (bij voorkeur ook), de connectie met je database, de tabel- en kolomtypen van je database en de data in de database zelf dienen alle dezelfde character encoding te hebben. Dit verdient de sterke voorkeur omdat er dan geen vertalingen uitgevoerd hoeven te worden, er geen verwarring kan ontstaan welke CE iets zou moeten hebben, en de kans op het corrupt raken van data geminimaliseerd wordt.

      Daarnaast, en misschien nog veel belangrijker, kun je er alleen vanuit gaan dat je output escaping (dit is o.a. wat via prepared statements gebeurt) goed werkt mits je character encoderingen goed zijn ingesteld. Dit is een noodzakelijke voorwaarde.

      Dan stopt het beveiligen van je website(s) niet bij het enkel escapen van de invoer. De data in je database is nog steeds voor een groot deel user input. Vertrouw nooit user input. Wat je dus ook moet doen als je data weer afdrukt op je scherm is deze escapen omdat hier mogelijk HTML, JavaScript of andere ongein in zit wat weer andere inbraakmogelijkheden beschikbaar maakt (cross site scripting et cetera).

      Een algemeen devies is nog steeds filter input, escape output. Daarnaast moet je security niet zien als één enkele ondoordringbare muur die je ergens opwerpt, en verder niets meer beveiligt "want de muur is toch ondoordringbaar". De beste manier van beveiligen is werken met (meerdere) lagen.

      MBCompany wrote:

      En wat kan ik doen aan :
      catch(PDOException $e){ echo $e->getMessage();}
      Zorgen dat heel je applicatie met exceptions werkt, en niet enkel je database. Vervolgens zet je één (of meer) try-catch blokken om je hele applicatie heen en bepaal je afhankelijk van het type gebruiker wat er moet gebeuren. Bijvoorbeeld een developer / IP-adres van de ontwikkelende partij ziet exceptions direct op het scherm, een bezoeker ziet een nette foutpagina of iets dergelijks.

      Ook moet je je het volgende realiseren: PDO is niet geschreven voor gebruik van een specifieke database. Dit heeft tot gevolg dat PDO op voorhand niet (optimaal) is geconfigureerd voor gebruik van database-type X.

      PDO heeft meerdere drivers voor verschillende database-typen. Ik neem aan dat je van plan bent om PDO te gebruiken om met MySQL-databases te communiceren? Het eerste wat ik zou doen is je verdiepen in de PDO_MYSQL driver. Het is een misconceptie om te denken dat PDO makkelijk is. Sure, je hebt een handjevol methoden die je (her)gebruikt, maar daar zit ook niet de leercurve. Deze zit in het je eigen maken van een correct gebruik van de driver(s) die je gebruikt.

      En dan nog iets over exceptions, ik denk dat je rekening moet houden met het volgende: een exception treed op als er iets onverwachts gebeurt. Maar dat houdt niet per se in dat je de exception dan en daar moet afhandelen met een catch-blok.

      Bij het opzetten van je MySQL-connectie via PDO kun je aangeven hoe fouten afgehandeld moeten worden (middels de parameter PDO::ATTR_ERROR_MODE PDO::ATTR_ERRMODE). Als je (in het algemeen) gebruik maakt van exceptions dan stel je de deze parameter in met de waarde PDO::ERRMODE_EXCEPTION. Dit zorgt ervoor dat als er een fout optreedt dat er (naast het instellen van errorcodes) een exception wordt gegenereerd.

      Exceptions moeten opgevangen worden, als dit niet gebeurt wordt er een fatal error geproduceerd. Wanneer je dus een applicatie hebt waarin exceptions worden gebruikt en dus kunnen optreden zal er dus ergens een try-catch blok moeten staan. Dit kun je bijvoorbeeld doen op applicatie-niveau. Als er op het database-niveau iets misgaat, dan hoef je niet per se een database-exception op dat niveau af te handelen als dit maar ergens in een bovengelegen laag gebeurt. Met het genereren van een exception zeg(t) je (code) in feite: "Ik weet niet wat ik hiermee aan moet, kan iemand dit mij vertellen?". Ergens moet er een antwoord op deze vraag gedefinieerd zijn.

      The post was edited 2 times, last by FangorN ().

    • Ook handig indien je streng wilt gaan beveiligen niet alleen database gerelateerd:

      owasp.org/index.php/Cross-Site…F)_Prevention_Cheat_Sheet

      En een handige functie om xss tegen te gaan en mijn huidige anti CSRF:
      Xss stop je door een input waarde van de gebruiker die moet opgeslagen worden in de database om terug te tonen op de website te escapen. Dit kan met $security->xssEscape($_POST['value']) vooralleer je de waarde gaat opslaan in de database.
      Zorg wel dat $security gedefineert is en dat deze de class security bevat. ($security = new Security();) En uiteraard, zorg er ook voor dat deze ge required word door je web app.

      CSRF stop je door een security token aan te maken voor iedere gebruker uniek. Na iedere form submit GET/POST/PUT/DELETE vergelijk je de securitytoken (meegegeven in de form als input hidden) met de huidige token van de gebruiker, indien gelijk (===) dan kan je de actie uitvoeren en een nieuwe scurity token gaan genereren voor de gebruiker en eventueel omleiden.

      Source Code

      1. class Security
      2. {
      3. /**
      4. * CSRF
      5. * */
      6. protected $token;
      7. public function __construct()
      8. {
      9. if(!isset($_SESSION['security_token']))
      10. {
      11. $_SESSION['security_token'] = self::createToken();
      12. }
      13. $this->token = $_SESSION['security_token'];
      14. }
      15. private function createToken()
      16. {
      17. $string = md5(uniqid(rand(), true));
      18. $hash = hash('sha256', $string);
      19. return $hash;
      20. }
      21. public function getToken()
      22. {
      23. return $this->token;
      24. }
      25. public function generateNewToken()
      26. {
      27. $_SESSION['security_token'] = self::createToken();
      28. $this->token = $_SESSION['security_token'];
      29. }
      30. public function xssEscape($input)
      31. {
      32. $output = htmlspecialchars(strip_tags($input));
      33. return $output;
      34. }
      35. }
      Display All

      En dan raad ik je ook aan je session_start(); op z'n minst de parameters correct in te vullen of gebruik te maken van een veilige session class of script die session hijacking tegen gaat.
      blog.teamtreehouse.com/how-to-create-bulletproof-sessions
      Web developer

      The post was edited 8 times, last by MiCa- ().

    • Bedankt, Ik zal het goed bekijken en toepassen.
      Misschien iemand nog een goede idee om een error handler? en het loggen ervan hoe het beste is?
      Ik sta open voor projecten.
      Ik sta ook tehuur als scripter
      PM voor meer informatie
    • @MiCa- ik denk dat je in je Security class een aantal zaken op één hoop gooit die niet echt met elkaar te maken hebben.

      Jouw class verzorgt enerzijds output escaping middels de xssEscape() methode en anderzijds zit hier functionaliteit in die middels een token-constructie de kans op CSRF kleiner maakt (maar niet uit sluit).

      Toegegeven, het heeft allebei met security te maken, maar het zijn wel twee compleet verschillende dingen. Ook zie ik niet helemaal waarom je een object van de Security class zou moeten maken? Waarom geen static helper methodes? getToken() ga je ook niet zo vaak gebruiken omdat je een page-request verder bent als je tokens uit $_POST en $_SESSION gaat vergelijken?

      Daarnaast zitten hier naar mijn mening twee (kapitale) fouten in:
      - je escapet hier input; het devies is filter INPUT, escape OUTPUT. Ik ben het eigenlijk wel eens met de stelling dat het op voorhand escapen van input een slecht idee is; wat als je dadelijk deze data wilt bewerken? Moet je dan de omgekeerde bewerking uitvoeren? Of er vanuit gaan dat er overal braaf is ge-escaped aan de invoerkant? Je voert ook strip_tags op de input uit, je gooit dan op voorhand al zaken weg; ook is de toestand van de data in je database niet heel erg duidelijk: is de xssEscape() al overal uitgevoerd? hoe kun je dit garanderen? Nee, het lijkt mij een veeeeeeeeeel beter plan om je data gewoon rauw op te slaan in je database en deze standaard niet te vertrouwen (het blijft user input), bij het afdrukken van deze data gebruik je pas functies zoals htmlspecialchars(); dit is wat bedoeld wordt met escape OUTPUT; tenzij het geauthenticeerde gebruikers zijn die je vertrouwt die deze data invoeren en/of wanneer je echt HTML wilt afdrukken (iets wat je met jouw insteek ook niet gaat bereiken); deze toepassing zal dan expliciet gedocumenteerd moeten worden (de reden dat je niet escapet) Maar dan moet je wel je opties openhouden en niet op voorhand het kind met het waswater weggooien

      - je roept htmlspecialchars() aan zonder de belangrijkste parameters! Je stelt geen flags in, dit is default ENT_COMPAT | ENT_HTML401 terwijl de "veiligste" variant ENT_QUOTES is (daarbij moet je er zorg voor dragen dat je HTML correct is en waarden van attributen tussen "dubbele quotes" staan; Daarnaast, en nog veel belangrijker, dit vormt haast de spil in output escaping in verschillende contexten (database, HTML), is: je specificeert geen character encoding; pas vanaf PHP 5.4 is dit standaard UTF-8 (daarvoor niet!), maar het lijkt mij veel veiliger om geen enkele ruimte voor eigen interpretatie open te laten en dit soort zaken altijd expliciet in te stellen; ik zeg het nogmaals: output escaping werkt alleen goed als alles omtrent character encoderingen klopt als een bus, anders kun je simpelweg niet garanderen dat je output escaping goed werkt!

      Twee statische helper functies (generateToken() en escapeHtml() of iets dergelijks) volstaan dus prima ter vervanging van bovenstaande class.

      @MBCompany ik zou eerder meer zorg besteden aan code die errors/exceptions voorkomt (die dus tegen een stootje kan / robuust is) dan investeren in uitgebreide error handling / logging.

      The post was edited 1 time, last by FangorN ().