Escapen van data in functiebieb (om te leren!!)

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

George van Baasbank

George van Baasbank

17/11/2013 11:24:25
Quote Anchor link
Goedemorgen allemaal,

Onlangs heb ik op deze site melding gemaakt van het feit dat een van mijn sites bezocht was door ongenode gasten. Achteraf bleek dat er het e.e.a. aan mijn beveiliging schortte.
Zo heb ik nu mijn queries voor DELETE, INSERT en UPDATE via een prepared statement laten lopen. Dit lijkt allemaal goed te gaan. In ieder geval komen de nieuwe waardes van de variabelen terecht in de juiste tabellen.
Nu gaat er de laatste tijd op dit forum een discussie rond over het escapen van input-data.
Nu heb ik voor mijzelf een functie opgenomen in mijn bibliotheek om alle input-data hierdoor te laten "schonen".
Graag hoor ik van jullie of deze schoning nog aanvulling behoeft.

Functie:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
<?php
function EscapeData($cDataVar) {
    $cDataVar = strip_tags($cDataVar);
    $cDataVar = htmlspecialchars($cDataVar);
    
    return($cDataVar);
}

?>


Deze functie pas ik op de volgende wijze toe in mijn script:

Script:
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<?php
if($_SERVER['REQUEST_METHOD'] === 'POST') {
    
    // Inlezen invulvelden
    $cNaamInzender = $_POST['naam'];
    $cEmailInzender = $_POST['email'];
    $cCorrectie = $_POST['bericht'];
    $cBestandsnaam = basename($_FILES['bestand']['name']);
        
    // Ontdoen van mogelijke verkeerde info
    $cNaamInzender = EscapeData(cNaamInzender);
    $cEmailInzender = EscapeData($cEmailInzender);
    $cBestandsnaam = EscapeData($cBestandsnaam);
    $cBestandsnaam = VertaalBestandsnaam($cBestandsnaam);
    $cCorrectie = EscapeData($cCorrectie);
    $cBestemming = "uploads/" . $cBestandsnaam;
    
    $cIdPersoon = $_SESSION['cx'];
    $cVersie = $_SESSION['versie'];
    $cPersoon1 = $_SESSION['persoonsnaam'];
    
    //Open de connectie met de database
    include "connectie_nw.inc.php";
    include "queries/sql_ins_correctie.php";
    
    // Create a prepared statement en bewaar de melding in de database
    $stmt=mysqli_stmt_init($verbinding);
    
    if (mysqli_stmt_prepare($stmt,$sql)) {

        // Execute query
        mysqli_stmt_execute($stmt);

        // Fetch value
        mysqli_stmt_fetch($stmt);

        // Close statement
        mysqli_stmt_close($stmt);
    }

    
    // Upload bijgesloten file
    // Brondoc: http://www.w3schools.com/php/php_file_upload.asp

    if ($_FILES["bestand"]["error"] > 0) {
        echo "Return Code: " . $_FILES["bestand"]["error"] . "<br>";
    }
else {
        if (file_exists("uploads/" . $_FILES["bestand"]["name"])) {
            echo $_FILES["bestand"]["name"] . " already exists. ";
        }
else {
            move_uploaded_file($_FILES["bestand"]["tmp_name"],$cBestemming);
        }  
    }

    mysqli_close($verbinding);
}

?>


Mijn vraag is dan ook: Zitten in beide scripts nog onvolkomenheden? Ik wil graag iets leren en geen aapje worden die een kunstje kent.....

George
 
PHP hulp

PHP hulp

21/11/2024 20:43:13
 
Erwin H

Erwin H

17/11/2013 11:36:00
Quote Anchor link
Bedenk wanneer je wat doet. Niet doen omdat het kan of omdat iemand het eens zegt.
Bijvoorbeeld strip_tags en htmlspecialchars, waarom doe je die voor je het in de database zet?
Ofwel je doet het na het weer uit de database halen en voor het versturen naar de browser. Je wil in principe namelijk de oorspronkelijke user input in je database hebben en niet een aangepaste versie. Heb je namelijk iets aangepast, dan kan je nooit meer de oorspronkelijke versie terughalen.
Ofwel je wil weten of er iets raars in je data zit, zodat je de hele insert kan voorkomen. Is er namelijk iemand bezig met een hack poging, en je ontdekt het in je code, dan is er geen enkele reden om de data alsnog in de database te zetten. Het is toch allemaal troep, dus stop met de hele actie in dat geval.

In beide gevallen is er dus geen reden om vooraf al die acties uit te voeren.

Een andere opmerking:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
<?php
$cNaamInzender
= $_POST['naam'];
$cNaamInzender = EscapeData(cNaamInzender);
?>

Hier doe je eigenlijk twee dingen verkeerd. In de eerste plaats check je niet of de key 'naam' wel bestaat in de $_POST array. Bestaat die niet dan gaat je script plat. Daarnaast kan het natuurlijk direct, in 1 regel (en sommige zullen zeggen dat je het onnodig in een variabele kopieert, daar ben ik het niet noodzakelijkerwijs mee eens)
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
if ( isset( $_POST['naam'] ) ){
  $cNaamInzender = EscapeData( $_POST['naam'] );
}
else {
  //doe iets, bijvoorbeeld default waarde, of breek het af omdat data ontbreekt
}
?>
Gewijzigd op 17/11/2013 11:44:46 door Erwin H
 
George van Baasbank

George van Baasbank

17/11/2013 12:17:55
Quote Anchor link
Erwin,

Dank voor je toelichting.

1. Het testen of de betreffende key bestaat ga ik overnemen.

2. Het langs de functie EscapeData laten lopen van de variabele zou volgens jou pas moeten bij het uitlezen van de tabel en niet bij het opslaan in de tabel. Is dit een keuze of is dit echt bittere noodzaak?

Toevoeging op 17/11/2013 12:28:08:

Erwin,

Nog een toevoeging: Ik gebruik in mijn html-deel wel de mogelijkheid om velden verplicht met het juiste format te laten invullen.

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
32
33
34
35
36
37
38
39
40
41
<div id="tabs-6" >
   <strong>Inzenden aanvulling</strong>
   <div class="regelhoogte25"></div>
   <?php if(!empty($errors)){ echo "<p class='err'>".nl2br($errors)."</p>"; } ?>
   <div id='contact_form_errorloc' class='err'></div>
   <form name="contact_form" action="persoonskaart.php?id=<?php echo $cX ; ?>" method="POST" enctype="multipart/form-data">
      <input type="submit" class="aanvulling" value="Insturen aanvulling" />
      <label for="naam">Uw naam:</label><br />
      <input type="text" name="naam" placeholder="Uw naam" required="" /><br />
      <label for="email">Uw e-mailadres:</label><br />
      <input type="email" name="email" placeholder="Uw e-mailadres" /><br />
      <label for="bestand">Evt. bestand:</label><br />
      <input type="file" name="bestand" /><br />
      <label for="bericht">Uw aanvulling:</label><br />
      <textarea name="bericht" style="margin-bottom: 5px!important; width: 300px!important;" ></textarea><br />
      <img src="captcha/captcha_code_file.php?rand=<?php echo rand(); ?>" id='captchaimg' ><br>
      <label for='message'>Controlecode. Neem het woord hierboven over</label><br />
      <input id="6_letters_code" name="6_letters_code" type="text" placeholder="Controlecode" required="" /><br />
      <small>Code onleesbaar? Klik <a href='javascript: refreshCaptcha();'>hier</a> voor een nieuwe code</small><br />
   </form>
   <script language="JavaScript">
      // Code for validating the form
      // Visit http://www.javascript-coder.com/html-form/javascript-form-validation.phtml
      // for details
      var frmvalidator  = new Validator("contact_form");
      //remove the following two lines if you like error message box popups
      frmvalidator.EnableOnPageErrorDisplaySingleBox();
      frmvalidator.EnableMsgsTogether();

      frmvalidator.addValidation("naam","req","Vul uw naam in");
      frmvalidator.addValidation("bericht","req","Vul uw bericht in");
      frmvalidator.addValidation("email","req","Vul uw e-mailadres in");
      frmvalidator.addValidation("email","email","Geen geldig e-mailadres");
   </script>
   <script language='JavaScript' type='text/javascript'>
      function refreshCaptcha() {
         var img = document.images['captchaimg'];
         img.src = img.src.substring(0,img.src.lastIndexOf("?"))+"?rand="+Math.random()*1000;
      }
   </script>
</div>
 
Erwin H

Erwin H

17/11/2013 13:09:58
Quote Anchor link
George van Baasbank op 17/11/2013 12:17:55:
2. Het langs de functie EscapeData laten lopen van de variabele zou volgens jou pas moeten bij het uitlezen van de tabel en niet bij het opslaan in de tabel. Is dit een keuze of is dit echt bittere noodzaak?

Wat je doet is daar niet escapen (ook al noem je het zo). Escapen is het onschadelijk maken van bepaalde karakters door er (over het algemeen) een andere karakter voor te zetten dat de database weet dat het als een normaal karaketer in de string moet worden gezien. Dat heb je normaal gesproken nodig in een query, maar niet meer op het moment dat je prepared statements gebruikt. Wat jij doet in je 'EscapeData' functie is het veranderen van bepaalde stukken in de string, normaal gesproken gebruikt om HTML injectie of XSS tegen te gaan.

Is het keuze om het op het ene moment of het andere te doen? Ja, uiteraard is dat een keuze. Waarom je het pas later zou moeten doen heb ik eerder uitgelegd.
 



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.