Ik ben bezig met het maken van een prive website waarbij ik gebruik maak van PHP en een MySQL database. Nu heb ik er geen moeite mee om de querys via PHP MyAdmin de database te vullen.
Nu is het de bedoeling dat ik dat via een webpagina ga doen, zodat ik de data op een snelle(re) manier kan invoeren. Op termijn is het de bedoeling dat anderen ook toegang krijgen tot de pagina en hiermee dus ook de database kunnen vullen.

Ik heb hieronder een stuk tekst met daaronder de betreffende code geplaatst, met daaronder een nieuw stuk tekst en een nieuw stuk code, etc.

Ik heb hiervoor een script gebruikt via http://www.sitemasters.be/tutorials/2/1/78/MySQL/Formulier. Zie ook hieronder. Dit werkt prima.
Ik roep de php pagina db_config aan waarin mijn inloggegevens staan voor de (lokale) database.


<?php 
require_once 'db_config.php'; //verbinding maken
mysql_select_db('rum') or die (mysql_error());  //errorhandling

if(isset($_POST['verzenden'])) 
  { 
    $sVoornaam        =    addslashes($_POST['voornaam']); 
    $sAchternaam      =    addslashes($_POST['achternaam']); 
    $iLeeftijd        =    addslashes($_POST['leeftijd']); 
     
    mysql_query("INSERT INTO formulier (voornaam, achternaam, leeftijd) VALUES ('".$sVoornaam."', '".$sAchternaam."', '".$iLeeftijd."')") or die (mysql_error()); 

    echo 'Je gegevens zijn succesvol in de database geplaatst'; 
  } 
else 
  { 
?> 
<form action=" <?=$_SERVER['PHP_SELF']?>  " method="POST">
 Voornaam: <input type="text" name="voornaam"><br /> 
Achternaam: <input type="text" name="achternaam"><br /> 
Leeftijd: <input type="text" name="leeftijd"><br /> 
<input type="submit" name="verzenden" value="verzenden"> 
</form> 
<? 
  } 
?> 



Ik heb een aantal waarden aangepast en ik heb er onderstaand van gemaakt. Als ik dit uitvoer krijg ik mijn pagina met textboxen en een verzend knop weer terug, maar er worden geen records in de tabel `nose` weggeschreven.



<?php    
require_once 'db_config.php'; //verbinding maken
mysql_select_db('rum') or die (mysql_error());  //errorhandling

if(isset($_POST['verzenden'])) 
  { 
    $cRumName        =    addslashes($_POST['RumName']); 
    $iAge		     =    addslashes($_POST['Age']); 
     
    mysql_query("INSERT INTO `nose` ('RumName', 'Age') VALUES ('".$cRumName."', '".$iAge."')") or die (mysql_error());
	

	
  }
else 
{
 
?> 
<form action=" <?=$_SERVER['PHP_SELF']?>  " method="POST">
Rumnaam: <input type="text" name="RumName"><br /> 
Leeftijd: <input type="text" name="Age"><br /> 
<input type="submit" name="Verzenden" value="Verzenden"> 
</form> 
<?php 
    } 
?> 



Ik heb ook een query gemaakt in PHP die uit dezelfde tabel de waarden naam en leeftijd teruggeeft en in een tabel plaatst op de site. Dit gaat zonder problemen. (De code hiervoor staat hieronder).



<?php
require_once 'db_config.php'; //verbinding maken
mysql_select_db('rum') or die (mysql_error());  //errorhandling
$query = "SELECT `Age`,`RumName` FROM `nose` WHERE `Age` > '5' ";
//query is aangemaakt
$sql = mysql_query($query) or die ( mysql_error( ) );
//query is uitgevoerd
echo"<table>
 <tr><td>Naam</td><td>Leeftijd</td></tr>";
while($record = mysql_fetch_object($sql)){
echo"<tr><td>".$record->RumName."</td><td>".$record->Age."</td></tr>";
}
echo"</table>";

?>


Eerst dacht ik aan een rechten probleem, omdat ik wel kan lezen, maar niet kan schrijven. Ik heb daarom het gekopieerde script nog een keer in mijn PHP pagina gebruikt om te zien of ik de voornaam, achternaam en leeftijd in een andere tabel in dezelfde database wel weg kan schrijven. Dat lukte wel, dus ik denk dat het veilig is om de aanname te doen dat er voldoende rechten zijn.
Ik had eigenlijk gehoopt dat het gedeelte 'or die (mysql_error());' er voor zou zorgen dat ik een foutmelding zou zien, maar dat gebeurt ook niet. Ik heb dus nu geen idee wat ik fout doe en waar ik het nog moet zoeken.
Waarschijnlijk is het voor de toppers hier een peuleschilletje, dus als iemand me op weg zou willen helpen zou ik zeer dankbaar zijn.
Mooi stuk.
En wat zou het mooi zijn als de topicstarter antwoordt met "k"... :D
kk :)

@Pg Vincent
Omdat quotes alleen de waarden afbakenen is het altijd beter om ze wel te gebruiken, dan om de queryparser te laten gokken over wat je bedoelt.
Als je waarden direct in een query plakt dan is het sowieso altijd verplicht om ze te quoten, want anders zet je je script open voor SQL injectie.

Ben ik het niet helemaal mee eens. Als je zorgt dat je je input filtert voor numerieke waarden zijn quotes (zelfs) helemaal niet nodig.

Het toevoegen van quotes alleen is ook niet genoeg, want magic_quotes_gpc() bestaat niet meer in nieuwere PHP-versies (dit biedt ook geen absolute garanties want en het was naar verluid niet eens voor security bedoeld maar kan wel wat (toevallige) bescherming bieden). Je kunt dus makkelijk uit deze quotes springen door constructies als ...' OR '1' = '1...

Daarnaast mogen de DATA-delen in je query niet behandeld worden als SQL, daarvoor is de MySQL-context-specifieke escaping functie/methode real_escape_string().
Het toevoegen van real_escape_string() alleen (zonder quotes) is OOK niet genoeg omdat er niets ge-escaped wordt als er niets te escapen valt, bijvoorbeeld met ...OR 1=1.... Het komt nogal eens voor dat real_escape_string() als een soort toverformule gebruikt wordt (SIMSALABIM!) en dat na afloop (ten onrechte) verondersteld wordt dat alles veilig is (terwijl geen quotes om het geheel waren geplaatst).

Alleen de combinatie van beide middelen (het toevoegen van quotes en het escapen van de inhoud met de daarvoor bestemde functie/methode) is veilig, en dan alleen wanneer je character encoderingen kloppen. Als deze niet kloppen / uit de pas lopen kan niet gegarandeerd worden dat de escaping goed gaat. Daarom geeft een (andere) escaping functie als htmlspecialchars() ook een lege string terug als de encodering van de string-parameter niet overeenkomt met de opgegeven encodering, omdat er dan simpelweg niet gegarandeerd kan worden dat het resultaat "HTML safe" is.

@Willem vp
De enige manier om je script te beveiligen is door alle input te sanitizen.

Als je met sanitizen bedoelt "repareren tot iets geldigs", ik zou het niet doen. Dat is toch net zoiets als typecasting. Als je bedoelt "filteren" dan ben ik akkoord. Als je input "niet past", gewoon weigeren.

Ik zie dit soort constructies te vaak:
<?php
$q = 'SELECT * FROM whatever WHERE id = '.((int) $_GET['id']);
?>

Als $_GET['id'] vervolgens 'aap' bevat wordt dit getypecast naar het cijfer 0. Maar het heeft (mogelijk) totaal geen zin om zo'n query uit te voeren omdat deze of geen, of onvoorspelbare resultaten oplevert. Onvoorspelbaar, omdat er met een typecast een interpretatiestap wordt uitgevoerd, "Oh hij zal wel X of Y bedoeld hebben".

Als je met sanitizen bedoelt "repareren tot iets veiligs", dan ben ik het daar ook niet mee eens, wat je dan in feite doet is 'escape-on-input'. Ook dat lijkt mij een slecht idee.

Idealiter sla je "geldige" data (dit hoeft niet per sé "wenselijke" data te zijn, hier mogen nog best dingen in zitten die bij een later gebruik schade aan kunnen richten) rauw op, zodat je deze later weer makkelijk kunt bewerken. Als je deze bijvoorbeeld opslaat met htmlentities() ofzo (Joost mag weten waarom), dan zul je op een zeker moment weer de omgekeerde bewerking uit moeten voeren. Dit brengt ook weer allemaal problemen met zich mee en in zijn algemeenheid wordt je applicatie complexer door dit soort vertaalslagen.

Ik ben van mening dat je invoer exact moet kloppen nog voordat je een query of wat dan ook uitvoert. Wat als dit een kostbare operatie is? Het is een verspilling van resources. Filter input, klopt je invoer niet, pech (maar doe niets!).

Als iederen zich nou gewoon van het devies filter input, escape output zou bedienen (en tevens begrijpt wat dit inhoudt)...
Eddy E op 01/11/2015 08:24:40

Mooi stuk.
En wat zou het mooi zijn als de topicstarter antwoordt met "k"... :D


"k"...
En gaaf om te zien hoe een vraag in een beginnersforum zo'n geweldige discussie ontketent!

Reageren