Hallo allemaal

Ik probeer momenteel mijn invoervelden veilig te maken tegen MYSQL injection. Is dit goed genoeg beveiligd?


$link = mysqli_connect($db_hostname, $db_username, $db_password, $db_database) or die("Error " . mysqli_error($link));
$bloopp = $_POST['bloopp'];
$bloopp = htmlspecialchars($bloopp);
$bloopp = mysqli_real_escape_string($link, $bloopp);
$bloopp = strip_tags($bloopp);
$search = array("'", '"', "--");
$replace = array("´", "$acute;", "_");
$bloopp = str_replace($search, $replace, $bloopp);


Alvast bedankt om een kijkje te nemen!
Sven
Het beveiligen van een applicatie start altijd met weten wat je doet, niet zo maar iets doen en dan hopen dan het veilig is. Als ik dit soort lijnen code zie vraag ik me altijd af of de kennis er wel is. Dus als eerste de vraag: waartegen wil je beveiligen? Probeer bij elke regel dan ook eens te vermelden waarom je die regel nodig denkt te hebben.
Je mist vooral controles. Ik zal ze voor je nummeren.

<?php
// (1) Is $_POST['bloopp'] ingesteld en (2) is $_POST['bloopp'] niet leeg?
if (isset($_POST['bloopp']) && !empty($_POST['bloopp'])) {
    // (3) Is $_POST['bloopp'] een string?
    if (is_string($_POST['bloopp'])) {
        // (4) Gebruikt deze server nog verouderde magic quotes?
        if (get_magic_quotes_gpc()) {
            $_POST['bloopp'] = strip_slashes($_POST['bloopp']);
        }
        $_POST['bloopp'] = strip_tags($_POST['bloopp']);
        $_POST['bloopp'] = htmlspecialchars($_POST['bloopp']);
        $link = mysqli_connect($db_hostname, $db_username, $db_password, $db_database);
        // (5) Is er geen fout opgetreden bij het openen van de databaseverbinding?
        if (!mysqli_connect_error()) {
            // (6) Kan de juiste MySQL-karakterset worden ingesteld?
            if (mysqli_set_charset($link, 'utf8')) {
                $_POST['bloopp'] = mysqli_real_escape_string($link, $_POST['bloopp']);
                // Hier een prepared statement opstellen en uitvoeren.
                // <...>
            }
        }
    }
}
?>
Beste Erwin

Ik heb inderdaad weinig kennis van beveiliging. Nu weet ik hoe ik duidelijk een script moet opstellen!

Beste Ward

Hartelijk dank voor het opstellen van een veilige code! Ik zal deze zo onmiddellijk veranderen!

Op de regel 'hier een prepared statement opstellen en uitvoeren', kan ik mijn eigenlijke code uitvoeren, zoals het controleren of het tijdverschil met de vorige bloopp groot genoeg is en vervolgens $_POST['bloopp'] naar de database verzenden?


 $check="SELECT TIMESTAMPDIFF(MINUTE, send_time, CURRENT_TIMESTAMP) AS 'diff' FROM bloopp WHERE email = '$email' ORDER BY bloopp_id DESC LIMIT 1";
 $res = mysqli_query($link, $check) or die("Error " . mysqli_error($res));
 $data = mysqli_fetch_array($res, MYSQLI_ASSOC);


Nogmaals erg bedankt! Het is altijd fijn om zeker te zijn dat je website veilig is! ;-)

Met vriendelijke groet
Sven
Sven, waarom voer je een query uit als ik tip dat een prepared statement veel veiliger is? Waarom verwerk je een array als je maar één record ophaalt?

Je gooit er ineens ook een onbekende en ongecontroleerde variabele $email in.

Wat Erwin zegt dus: probeer eerst te begrijpen wat je per regel doet.
Sven Thijssen op 09/11/2013 16:40:02

Nogmaals erg bedankt! Het is altijd fijn om zeker te zijn dat je website veilig is! ;-)

Dat weet je helemaal niet....
Ward

Omdat ik niet wist wat een prepared statement is. Ik dacht dat dit gewoon de verdere code was, wat dus blijkbaar niet zo blijkt te zijn. Dit heb ik nu opgezocht op Wikipedia en ik heb dit gevonden:

$stmt = $dbh->prepare("SELECT * FROM users WHERE USERNAME = ? AND PASSWORD = ?");
$stmt->execute(array($username, $password));

Is zoiets in het algemeen wat U bedoelt?

Mijn kennis PHP is zeer gebrekkig en vind het meestal nogal moeilijk om ergens een verschil in te zien, zoals die array.
Ik hoop verder dat ik uit deze fouten kan leren. :)

Bedankt!
Wat je in je voorbeeld hierboven hebt aangegeven is inderdaad een prepared statement. Wat het voordeel hiervan is is dat de input, oftewel je $username en je $password, door de statement afgehandeld worden. Dat betekent dat er niet per ongeluk platte tekst of gekke tekens in je query komen te staan die gevaarlijke zaken kunnen uitvoeren op je database.

@Ward maakt het echt uit? Hoe dan ook moet de output van de query buffer nog geleegd worden
@Erwin lekker constructief, geef ook aan waarom dat dan niet zo is
Juist als je niet exact weet wat je wanneer moet controleren, helpt een prepared statement. De query wordt strikt gescheiden van de data die je er later insteekt: iets anders uitvoeren dan jouw query wordt onmogelijk.

Dus even praktisch: ja, herschrijf je MySQLi-code naar een prepared statement.
Pieter Jansen op 09/11/2013 23:30:36

@Erwin lekker constructief, geef ook aan waarom dat dan niet zo is

Lees mijn eerste post en je hebt je antwoord.

Oké, is zal binnenkort opnieuw schrijven als een prepared statement! Erg bedankt allemaal voor de hulp! ;)

Reageren