Ben ik beschermd tegen SQL injection?

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Ventilatiesysteem Productontwikkelaar HBO WO Verwa

Samengevat: Zij bieden flexibele ventilatiematerialen, geluidsdempers, rookgasafvoer producten en industrieslangen. Ben jij een technisch productontwikkelaar? Heb jij ervaring met het ontwikkelen van nieuwe producten? Vaste baan: Technisch Productontwikkelaar HBO WO €3.000 - €4.000 Zij bieden een variëteit aan flexibele ventilatiematerialen, geluiddempers, rookgasafvoer producten, industrieslangen en ventilatieslangen voor de scheepsbouw. Met slimme en innovatieve materialen zorgen wij voor een gezonde en frisse leefomgeving. Deze werkgever is een organisatie die volop in ontwikkeling is met hardwerkende collega's. Dit geeft goede ontwikkelingsmogelijkheden. De branche van dit bedrijf is Techniek en Engineering. Functie: Voor de vacature als Technisch Productontwikkelaar Ede Gld HBO WO ga

Bekijk vacature »

Pagina: « vorige 1 2 3

Ward van der Put
Moderator

Ward van der Put

17/12/2014 17:01:15
Quote Anchor link
Heet het eerste PHP-bestand test.php?
Staat de foutafhandeling voor de database in login.php?
Wat is issset.php?
Gewijzigd op 17/12/2014 17:02:48 door Ward van der Put
 
PHP hulp

PHP hulp

24/04/2024 17:15:21
 
Michael Desmadril

Michael Desmadril

17/12/2014 21:43:45
Quote Anchor link
Het eerste bestand heet test.php

in mijn login php file staat gewoon:

$db_host = "localhost";
$db_username = " blablabla";
$db_password = " blablabla";
$db_database = "blablabla";


issset.php is mijn php code die ik gelinkt heb

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
    
    require_once 'login.php';
    $db_con= new mysqli($db_host, $db_username, $db_password, $db_database);
    $db_con->set_charset("utf8");
    if($db_con->connect_error) die ("(" . $db_con->connect_error . " Error during connection");

    if(isset($_POST['zoeken'])){


    $zoeknaam = $_POST['Zoek']; // declare the input here
    $stmte = $db_con->prepare("SELECT * FROM customers WHERE Voornaam = ?");
    $stmte->bind_param("s", $zoeknaam); // then use inside here
    $stmte->execute();


    $rows = $stmte->num_rows;

    if($stmte->num_rows > 0) {
    $results = $stmte->get_result();
    while($row = $results->fetch_assoc()) {
    
    echo $row['Achternaam'] . '<br/>';
        // and other columns
  
}
}
}



?>
Gewijzigd op 17/12/2014 21:45:28 door Michael Desmadril
 
Paco de Wulp

Paco de Wulp

05/05/2015 16:23:29
Quote Anchor link
Even een vraagje over het SQL-injection probleempje. -->

Buiten dat het moet gebeuren voor je login variabelen , om ze af te vangen met 'mysgl_real_escape_string', moet het ook voor alle andere velden in je systeem. Dus bij registratie van NAW, Bankrekeningnummer (IBAN), etc, ??
 
- Ariën  -
Beheerder

- Ariën -

05/05/2015 16:26:54
Quote Anchor link
Kort antwoord: Op alle data die een gebruiker maar invoert of aan kan passen moet je controleren of de inhoud schadelijke data bevat.
Ik neem ook dat dat geldt voor je NAW-gegevens en bankrekeningsnummers.

Dus ja, ook hierbij geldt dat je het moet escapen. Verder is gebruik van de mysql_*() extentie afgeraden, en wordt PDO of MySQLi aangeraden.
Gewijzigd op 05/05/2015 16:27:33 door - Ariën -
 
Paco de Wulp

Paco de Wulp

05/05/2015 16:32:45
Quote Anchor link
Maar je kan die velden toch ook wel afvangen met javascript ?
 
- Ariën  -
Beheerder

- Ariën -

05/05/2015 16:34:45
Quote Anchor link
Ja, maar Javascript werkt lokaal, en is uit te zetten/manipuleren.
Dus als je valideert:

- Validatie reeks controle (mailadres, telefoonnummer, website, etc...)
- SQL injection filteren
- Input validatie met JavaScript/HTML5
Gewijzigd op 05/05/2015 16:35:16 door - Ariën -
 
Paco de Wulp

Paco de Wulp

05/05/2015 16:40:54
Quote Anchor link
Duidelijke taal Aar ! Dank je.
 
Eddy E

Eddy E

05/05/2015 17:22:08
Quote Anchor link
Waarom zou je het risico lopen dat ergens $db_username of $db_password wordt weergeven?
Zet die gewoon NIET in variabelen, maar hardcoded in de code.
Nu doe je dat ook, maar wel via een variabele. Geen enkel voordeel, alleen maar mogelijke nadelen.

Dus doe het zo:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php

// require_once 'login.php';
    $db_con= new mysqli("localhost", "gebruikerX", "kdeN3nen_83", "database");
    $db_con->set_charset("utf8");

?>
Gewijzigd op 05/05/2015 17:28:25 door Eddy E
 
- Ariën  -
Beheerder

- Ariën -

05/05/2015 17:27:53
Quote Anchor link
Waarom zou je die variabelen ook echo'en? Je kan ze ook direct weer unset()-en nadat je ze gebruik hebt in de connectie. Dan kan niemand ze echo'en via een exploit ofzo.

Verder was die reactie waarop je reageert van iemand anders, en inmiddels gedateerd. Dit even ter informatie.
Gewijzigd op 05/05/2015 17:28:35 door - Ariën -
 
Thomas van den Heuvel

Thomas van den Heuvel

05/05/2015 20:23:21
Quote Anchor link
Eddy E op 05/05/2015 17:22:08:
Waarom zou je het risico lopen dat ergens $db_username of $db_password wordt weergeven?
Zet die gewoon NIET in variabelen, maar hardcoded in de code.

Als je je daar druk om moet maken, heb je problemen van een hele andere orde. Daarmee geef je in feite toe dat je niet in kunt staan voor de veiligheid van je eigen code.

Het is heel goed denkbaar dat je dit soort parameters wilt vangen in variabelen, bijvoorbeeld in een configuratie-bestand dat verschillende waarden heeft voor een vaste set parameters op grond van bijvoorbeeld een hostname.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
switch ($_SERVER['HTTP_HOST']) {
    // development
    case 'mysite.dev':
        $config->database = array(
            'user'     => '...',
            'pass'     => '...',
            'database' => '...',
            // etc...
        );
        // more host specific config...
        break;
    // production
    case 'mysite.com':
        $config->database = array(
            'user'     => '...',
            'pass'     => '...',
            'database' => '...',
            // etc...
        );
        // more host specific config...
        break;
    default:

        die('unknown hostname');
}

?>

Zoals gezegd, als iemand het op een of andere manier voor elkaar krijgt om de inhoud van $config af te drukken, dan wil dat zeggen dat iemand op een of andere manier PHP-code kan uitvoeren. Dan ben je al nat.

Dit klinkt als een soort mantra wat je je ooit hebt aangeleerd, maar waarvan je niet meer precies weet waarom het ook alweer zo zou zijn.

Ontopic: ik vind het grappig dat er zoveel nadruk wordt gelegd op het escapen van van alles en nog wat op het gebied van MySQL, en vervolgens druk je data die uit je database komt gewoon af, zonder deze te escapen :D. Dan mis je toch een beetje het punt geloof ik.

Vertrouw nooit user input. Ook / vooral niet nadat je deze hebt opgeslagen in je database lol.
 

16/05/2015 23:41:19
Quote Anchor link
SQL Injection is wat het aangeeft: dat iemand zonder het weten of te mogen data kan aanleveren die door de database wordt herkend als SQL. Ofwel dat het niet duidelijk is voor de database welk deel nu de SQL code is, en welk deel de data. Het grootste probleem is dat je als PHP programmeur soms zoveel met queries werkt dat het een klus kan zijn om alle queries adequaat te beschermen.
Meestal wordt aangeraden om mysqli_real_escape_string() te gebruiken. Maar dat werkt niet altijd, bijvoorbeeld als je een ID wilt escapen en iemand gebruikt '1 OR 1=1'. Dan moet je in ieder geval nog alle data checken op type, dat is al een hele klus.
Daarom is de enige aanbevolen manier om met prepared statements te werken. Omdat het aanbieden van de query en de data in gescheiden stappen gaat, is er voor de database geen misverstand wat precies de query is en wat de data is.
 
Paco de Wulp

Paco de Wulp

17/05/2015 14:04:46
Quote Anchor link
Laatste tijden veel aan mijn PHP-scrips verbeterd.
1) Quote's regeltjes consequent overal toegepast (wanneer enkele quotes en wanneer dubbele quotes)
2) Overgestapt van PHP 5.3.29 naar PHP 5.5.24
3) MySQL-statements omgezet naar MySQLi
4) SQL-injection d.m.v. mysqli_real_escape_string afgevangen
5) Password encryptie toegepast (password_hash, password_verify, password_needs_rehash)
6) Javascripts verbeterd (o.a. IBAN check toegevoegd)

Nu zit ik nog met 2 puntjes:

1) Ik wil 'prepared statements' gaan toepassen om het nog veiliger te maken.
Mijn vraag is: Is het zinvol om gewoon alle SQL-statements om te zetten naar een versie van prepared statements ? Kan ik dus al mijn mysqli_real_escape_string-statements er weer uitgooien ?

2) Ik zit nog met een vraag (waarschijnlijk een domme vraag).
Ik heb middels javascript alle velden gecontroleerd (of het een juist IBAN-nummer is, of het veld niet leeg is, of de datum-va/dataum-tm goed zijn ingevuld, etc...). Moet ik nu alle javascript-controles ook nog eens bij de PHP-validaties doen? Want ik begrijp dat je javascript uit kan zetten en dan worden er geen javascript-validaties gedaan. Maar is dit niet allemaal een beetje dubbel op ??

Toevoeging op 17/05/2015 16:05:18:

3de puntje:
AJAX maakt gebruik van javascript. Wanneer javascript wordt uit gezet in de browser werkt AJAX dan ook niet meer ?
Gewijzigd op 17/05/2015 14:13:47 door Paco de Wulp
 
Ward van der Put
Moderator

Ward van der Put

17/05/2015 16:22:18
Quote Anchor link
>> 1) Ik wil 'prepared statements' gaan toepassen om het nog veiliger te maken.
Mijn vraag is: Is het zinvol om gewoon alle SQL-statements om te zetten naar een versie van prepared statements ?

Nee, het gaat alleen om de injectie van buitenaf. SQL-expressies die geen output van buitenaf bevatten, kunnen niet met SQL-injectie worden misbruikt.

>> Ik heb middels javascript alle velden gecontroleerd (of het een juist IBAN-nummer is, of het veld niet leeg is, of de datum-va/dataum-tm goed zijn ingevuld, etc...). Moet ik nu alle javascript-controles ook nog eens bij de PHP-validaties doen?

Ja. Niet alleen kan JavaScript worden uitgezet: een hacker kan elk HTTP-request veranderen. Alle input die van buiten komt is dus bij voorbaat verdacht, totdat je met controles hebt bewezen dat deze ermee door kan.
 
Paco de Wulp

Paco de Wulp

17/05/2015 19:07:59
Quote Anchor link
Dank je @Ward.
ad.1)Maar wat is erop tegen om alles met prepared-statements doen? Het kan toch geen kwaad. Je hanteert dan wel tenminste overal dezelfde methodiek. Of heeft het andere consequenties voor bijvoorbeeld de performance, of is het niet sjiek om iets-wat overbodige statements in je code te hebben ?

ad.2)Dus eigenlijk kan je alle javascript checks skippen, want alles moet toch in PHP worden gecheckt. Eigenlijk zijn javascripts dus alleen maar voor een iets mooiere schermafhandeling, qua foutmeldingen en ander soort meldingen. Toch ?

ad.3) Maar hoe zit het dan met AJAX die ook gebruik maakt van javascript ?
 
Frank Nietbelangrijk

Frank Nietbelangrijk

17/05/2015 19:26:44
Quote Anchor link
1) Er is niets op tegen om alles met prepared statements te doen. Al zou het iets trager zijn dan merk je daar helemaal niets van. Maar Ward heeft gelijk. Vaste queries zonder variabelen van buitenaf zijn voor een buitenstaander ook niet te misbruiken.

2) Alles moet met PHP gevalideerd worden. Het is echter vaak wel gebruiksvriendelijk om ook javascript validatie te gebruiken. Denk bijv. aan een vakje dat direct rood wordt nadat de focus van het veld af is.
De gebruiker kan nu direct het vakje alsnog juist invullen en hoeft later niet nog een keer terug.
Persoonlijk vind ik dat met de komst van HTML5 de javascript validatie grotendeels weggelaten kan worden. Nu heb je immers de mogelijkheid om een input type "email" en "numeric" e.d. te maken.

3)Ook bij AJAX moet je serverside valideren en kun je om het gebruiksvriendelijker te maken ook clientside valideren.
Gewijzigd op 17/05/2015 19:57:43 door Frank Nietbelangrijk
 
Thomas van den Heuvel

Thomas van den Heuvel

17/05/2015 20:02:20
Quote Anchor link
Paco de Wulp op 17/05/2015 14:04:46:
4) SQL-injection d.m.v. mysqli_real_escape_string afgevangen

Mijn god daar gaan we weer.

mysqli_real_escape_string is geen wondermiddel.

Stel dat jij een query hebt waar je voor een zekere parameter een getal verwacht, zet je daar dan quotes omheen?

Bijvoorbeeld: SELECT * FROM users WHERE user_id = $x.

$x komt bijvoorbeeld uit $_GET['id'].

Als je geen quotes gebruikt doet je real_escape_string niets. Als $_GET['id'] "OR 1 = 1" bevat (zonder dubbele quotes) dan wordt er niets geescaped omdat er niets te escapen valt.

Als je wel quotes gebruikt... ik weet niet, het is wel "veilig" in combinatie met mysqli_real_escape_string() maar het is nogal onzinnig.

Als je prepared statement gebruikt... doe je een hoop werk voor niets als je het mij vraagt. prepare(), bind_param(), etc. Aint nobody got time fo dat.

Bottom line: als je een getal verwacht controleer dan op een getal. Oftewel filter je input. Als je invoer niet voldoet aan een zeker formaat dan hoef je ook geen query uit te voeren die niets oplevert.
 
Paco de Wulp

Paco de Wulp

17/05/2015 20:19:24
Quote Anchor link
Dank je @Frank. Duidelijk.
@Thomas, mij hoor je er niet meer over...ik snap het nu. Be Happy !!
 
Thomas van den Heuvel

Thomas van den Heuvel

17/05/2015 20:32:09
Quote Anchor link
Ik zie nergens filter input, escape output staan dus ik behoud mij het recht voor enige reserveringen te hebben (en te houden) ten aanzien van bovenstaande stelling.

Je "regels" zijn ook voornamelijk gericht op het buiten houden van rotzooi, maar over een verdere behandeling van "user data" hoor ik je niet. Tenzij jij bepaalde gebruikers in je systeem/systemen vertrouwt (middels een soort van chain-of-trust waarbij privileges worden doorgegeven) moet je alle user data blijven behandelen als zijnde onbetrouwbaar, zelfs (en wellicht vooral) als deze opgeslagen is in je database.
 
Paco de Wulp

Paco de Wulp

17/05/2015 23:15:53
Quote Anchor link
Ik neem alle hints, suggesties, tips mee. Wat een fantastische website is dit toch !
 

18/05/2015 22:22:48
Quote Anchor link
AJAX is ook maar een soort 2e 'headless' browser die op de achtergrond HTTP requests doet, net als de browser. Alleen dan gebeurt het met een XMLHTTPRequest (XHR) object, in plaats van dat de gebruiker een URL typt/klikt/afvuurt. Voor Javascript hoeft er verder niets speciaals gedaan te worden, zolang je de inputvariabelen maar controleert en schoont voordat je ze bij een SQL query in stopt. Hiervoor gelden dus dezelfde regels, en kan ik prepared statements aanbevelen.
 

Pagina: « vorige 1 2 3



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.