Is mijn formulier goed en veilig gemaakt?

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Max PHP

Max PHP

08/02/2017 15:42:36
Quote Anchor link
Ik heb onderstaand formulier gemaakt dat de data opslaat in een MySQL database.
Het telefoonveld checkt niet op de geldigheid van een telefoonnummer omdat ik niet weet hoe dat moet, ik vermoed met regex maar snap daar nog niets van. Het zou Belgische en Nederlandse nummers moeten toelaten dus +, ., -, (, ), spatie en getallen mogen alleen ingevuld worden.

Voor de rest werkt alles zoals ik het wil maar ik vraag me af of alles wel op een goede manier geschreven is en ook veilig is? Pas ik de htmlspecialchars, stripslashes etc. op de juiste manier toe? Want daar ben ik niet 100% zeker van.

Als er iemand goede actuele online leesvoer met voorbeelden weet of video tutorials op Youtube omtrent beveiliging van PHP en MySQL dan hoor ik het graag.
Er is zoveel te vinden online maar het meeste is al jaren oud en ik ben te noob/onwetend om het goede van het slechte te onderscheiden.

Alle kritiek is welkom!

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
<?php
    $servername
= "localhost";
    $username = "root";
    $password = "";
    $dbname = "form_security_test";
    $dbc = mysqli_connect($servername, $username, $password, $dbname);
    
    if (!$dbc) {
        die("Connection failed: " . mysqli_connect_error());  
    }


    $sql_gebruiker = "SELECT * FROM gebruiker WHERE gebruiker_id = '1'";
    $run_gebruiker = mysqli_query($dbc, $sql_gebruiker);
    $toon_gebruiker = mysqli_fetch_assoc($run_gebruiker);

    $naam = stripslashes($toon_gebruiker['naam']);
    $geslacht = stripslashes($toon_gebruiker['geslacht']);
    $leeftijd = stripslashes($toon_gebruiker['leeftijd']);
    $email = stripslashes($toon_gebruiker['email']);
    $telefoon = stripslashes($toon_gebruiker['telefoon']);
    $land = stripslashes($toon_gebruiker['land']);
    $van = stripslashes($toon_gebruiker['van']);
    $tot = stripslashes($toon_gebruiker['tot']);
    $nieuwsbrief = stripslashes($toon_gebruiker['nieuwsbrief']);

    if(isset($_POST['submit'])){
        $naam = trim($_POST['naam']);
        if(!empty($naam)){
            $naam = htmlspecialchars(mysqli_escape_string($dbc, $naam)) ;         
            $success[] = "Naam is: " . stripslashes(ucfirst($naam));
        }
else{
            $errors[] = "Naam is verplicht!";
        }

        if(!empty($_POST['geslacht'])){            
            $geslacht = mysqli_escape_string($dbc, $_POST['geslacht']);
            $success[] = "Geslacht is: " . $geslacht;
        }
else{
            $errors[] = "Geslacht is verplicht";
        }

        if(!empty($_POST['leeftijd'])){
            $leeftijd = trim($_POST['leeftijd']);
            if (is_numeric($leeftijd)) {
                $leeftijd = mysqli_escape_string($dbc, $leeftijd);
                $success[] = "Leeftijd is: " . $leeftijd . " jaar.";
            }
else{
                $errors[] = "Leeftijd mag alleen uit cijfers bestaan!";
            }
        }
else{
            $leeftijd = 0;
        }

        if(!empty($_POST['email'])){
            $email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
            if(filter_var($email, FILTER_VALIDATE_EMAIL)){
                $email = htmlspecialchars(mysqli_escape_string($dbc, $email));
                $success[] = "Email is: " . stripslashes($email);
            }
else{
                $errors[] = "Ongeldig e-mailadres!";
            }
            
        }
else{
            $errors[] = "E-mail is verplicht!";
        }

        if(!empty($_POST['telefoon'])){
            $telefoon = trim($_POST['telefoon']);
            if(strlen($telefoon) <= 23){
                $telefoon = htmlspecialchars(mysqli_escape_string($dbc, $telefoon));
                $success[] = "Telefoon is: " . stripslashes($telefoon);
        }
else{
            $errors[] = "Telefoon is te lang!";
        }
            
        }
else{
            $errors[] = "Telefoonnummer is verplicht!";
        }

        if(!empty($_POST['land'])){
            $land = mysqli_real_escape_string($dbc, $_POST['land']);
            $success[] = "Land is: " . stripslashes($land);
        }
else{
            $errors[] = "Selecteer een land!";
        }

        if(!empty($_POST['van']) && !empty($_POST['tot'])){
            $van = mysqli_escape_string($dbc, $_POST['van']) . ":00:00";
            $tot = mysqli_escape_string($dbc, $_POST['tot']) . ":00:00";
            $success[] = "Beschikbaar: van " . $van . " uur tot " . $tot . " uur";
        }
elseif(!empty($_POST['van']) && empty($_POST['tot'])){
            $errors[] = "Van en tot zijn beide verplicht als je ze niet leeg laat!";
        }
elseif(empty($_POST['van']) && !empty($_POST['tot'])){
            $errors[] = "Van en tot zijn beide verplicht als je ze niet leeg laat!";
        }
else{
            $van = "11:11:11";
            $tot = "11:11:11";
        }

        if(!empty($_POST['nieuwsbrief'])){
            $nieuwsbrief = mysqli_escape_string($dbc, $_POST['nieuwsbrief']);
        }
else{
            $nieuwsbrief = 0;
        }


        if(!isset($errors)){
            if(mysqli_num_rows($run_gebruiker) > 0){ // db record bestaat dus updaten
                $update_gebruiker = "UPDATE gebruiker SET naam = '$naam', geslacht = '$geslacht', leeftijd = '$leeftijd', email = '$email', telefoon = '$telefoon', land = '$land', van = '$van', tot = '$tot', nieuwsbrief = '$nieuwsbrief' WHERE gebruiker_id = '1'";
                if($run_update_gebruiker = mysqli_query($dbc, $update_gebruiker)){

                    $update_success = "<h4>Record bestaat al dus geupdatet. Update gelukt!</h4>";
                }
else{
                    $update_error = "<h4>Updaten is mislukt, probeer nog eens. Werkt het toch niet, contacteer ons dan aub:</h4> " . mysqli_error($dbc);
                }
            }
else{ // db record bestaat nog niet dus inserten
                $gebruiker_id = 1;
                $insert_gebruiker = "INSERT INTO gebruiker (gebruiker_id, naam, geslacht, leeftijd, email, telefoon, land, van, tot, nieuwsbrief)
                VALUES ('$gebruiker_id', '$naam', '$geslacht', '$leeftijd', '$email', '$telefoon', '$land', '$van', '$tot', '$nieuwsbrief')"
;
               if($run_insert_gebruiker = mysqli_query($dbc, $insert_gebruiker)){
                    $insert_success = "<h4>Nieuwe record aangemaakt. Uw gegevens zijn opgeslagen.</h4>";
               }
else{
                $insert_error = "<h4>Inserten is mislukt- Er is iets mis gegaan, probeer nog eens. Werkt het toch niet, contacteer ons dan aub:</h4> " . mysqli_error($dbc);
               }
            }
        }
    }

?>

<!DOCTYPE html>
<html lang="">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Title Page</title>

        <!-- Bootstrap CSS -->
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">

        <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
        <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
        <!--[if lt IE 9]>
            <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.2/html5shiv.min.js"></script>
            <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
        <![endif]-->
    </head>
    <body>
        <div class="container">
            <form action="" method="post">
                <?php if(isset($errors)){
                            echo
                                '<div class="alert alert-danger alert-dismissable">
                                <a href="#" class="close" data-dismiss="alert" aria-label="close">&times;</a>'
;
                                if(isset($update_error)){ echo $update_error;}
                                if(isset($insert_error)){ echo $insert_error;}
                                echo '<ul>';
                                foreach($errors as $error){
                                echo  '<li>' . $error . '</li>';
                                    }

                                echo '</ul></div>';
                        }

                    if(isset($success)){
                        echo
                            '<div class="alert alert-success alert-dismissable">
                            <a href="#" class="close" data-dismiss="alert" aria-label="close">&times;</a>'
;
                            if(isset($update_success)){ echo $update_success;}
                            if(isset($insert_success)){ echo $insert_success;}
                            echo '<ul>';
                            foreach($success as $success2){
                            echo '<li>' . $success2 . '</li>';
                            }

                            echo '</ul></div>';
                    }

                ?>

                <div class="row">
                    <div class="form-group col-sm-4">
                        <label for="usern">Naam: *</label>
                        <input type="text" name="naam" class="form-control" id="usern" value="<?php if(isset($naam)){ echo stripslashes($naam);} ?>" placeholder="naam">
                    </div>
                </div>
                <div class="form-group row">
                    <label class="col-md-2 control-label" for="geslacht">Geslacht: *</label>
                        <div class="col-md-10">
                            <label class="radio-inline" for="geslacht-0">
                                <input type="radio" name="geslacht" id="geslacht-0" value="1"<?php if(!empty($geslacht) == 1){echo " checked";} ?>>Vrouw
                            </label>
                            <label class="radio-inline" for="geslacht-1">
                                <input type="radio" name="geslacht" id="geslacht-1" value="2"<?php if(!empty($geslacht) == 2){echo " checked";} ?>>Man
                            </label>
                        </div>
                </div>
                <div class="row">
                    <div class="form-group col-sm-4">
                        <label class="control-label" for="leeftijd">Leeftijd:</label>
                        <div class="input-group">
                            <input type="text" name="leeftijd" id="leeftijd" class="form-control input-md" value="<?php if(!empty($leeftijd) > 0){echo $leeftijd;}  ?>" placeholder="Leeftijd">
                            <span class="input-group-addon">jaar</span>
                        </div><span class="help-block"><small>Bv: 26.</small></span>
                    </div>
                </div>
                <div class="row">
                    <div class="form-group col-sm-4">
                        <label for="email">E-mail: *</label>
                        <input type="text" name="email" class="form-control" id="email" value="<?php if(isset($email)){ echo stripslashes($email);} ?>" placeholder="E-mail">
                    </div>
                </div>
                <div class="row">
                    <div class="form-group col-sm-4">
                        <label for="tel">Telefoon: *</label>
                        <input type="text" name="telefoon" class="form-control" id="tel" value="<?php if(isset($telefoon)){ echo stripslashes($telefoon);} ?>" placeholder="Telefoon">
                    </div>
                </div>
                <div class="form-group row">
                    <div class="col-sm-5 col-md-4 col-lg-4">
                        <label for="land">Land: *</label>
                        <select class="form-control" name="land" id="land">
                            <option value=""<?php if(empty($land)){ echo " selected";} ?>>- Selecteer land -</option>
                            <option value="1"<?php if(isset($land) && $land == 1){ echo " selected";} ?>>Belg&euml;</option>
                            <option value="2"<?php if(isset($land) && $land == 2){ echo " selected";} ?>>Nederland</option>
                        </select>
                    </div>
                </div>
                <div class="row">
                    <div class="form-group col-sm-6 col-md-6 col-lg-6">
                        <div class="form-group"><label for="beschikbaar">Beschikbaarheid:</label>
                            <div class="row">
                                <div class="col-sm-5 col-md-4 col-lg-4">
                                    <select class="form-control" name="van" id="beschikbaar">
                                        <option value=""<?php if(isset($van) && $van == "11:11:11"){ echo " selected";} ?>>- Van -</option>
                                        <option value="00"<?php if(isset($van) && $van == "00:00:00"){ echo " selected";} ?>>00u00</option>
                                        <option value="1"<?php if(isset($van) && $van == 1){ echo " selected";} ?>>01u00</option>
                                        <option value="23"<?php if(isset($van) && $van == 23){ echo " selected";} ?>>23u00</option>
                                    </select>
                                </div>
                                <p class="col-sm-2 text-center">tot</p>
                                <div class="col-sm-5 col-md-4 col-lg-4">
                                    <select class="form-control" name="tot" id="m">
                                        <option value=""<?php if(isset($tot) && $tot == "11:11:11"){ echo " selected";} ?>>- Tot -</option>
                                        <option value="00"<?php if(isset($tot) && $tot == "00:00:00"){ echo " selected";} ?>>00u00</option>
                                        <option value="1"<?php if(isset($tot) && $tot == 1){ echo " selected";} ?>>01u00</option>
                                        <option value="23"<?php if(isset($tot) && $tot == 23){ echo " selected";} ?>>23u00</option>
                                    </select>
                                </div>
                            </div>
                        </div>
                      </div>
                  </div>
                <div class="row">
                    <div class="checkbox">
                        <label for="nieuwsbrief">
                            <input type="checkbox" name="nieuwsbrief" id="nieuwsbrief" value="1"<?php if(!empty($nieuwsbrief) == 1){ echo " checked";} ?>> Ontvang nieuwsbrief
                        </label>
                    </div>
                </div>

                <input type="submit" name="submit">
            </form>
        </div>
    </body>
</html>
Gewijzigd op 08/02/2017 15:47:04 door Max PHP
 
PHP hulp

PHP hulp

28/03/2024 13:07:49
 
- Ariën  -
Beheerder

- Ariën -

08/02/2017 15:53:45
Quote Anchor link
Die stripslashes() zijn verder niet nodig. Waarom zou je die willen strippen?
Als je de boel veilig wilt hebben tegen SQL-injectie, dan is mysqli_real_escape_string() de beste oplossing zolang je de 'ge-escapede' data in de query verwerkt.

Ook raad ik aan om de controle om iets verstuurd te hebben via POST aan te passen naar van
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
    if(isset($_POST['submit'])){


naar:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
if($_SERVER['REQUEST_METHOD'] == "POST") {
Gewijzigd op 08/02/2017 15:55:42 door - Ariën -
 
Thomas van den Heuvel

Thomas van den Heuvel

08/02/2017 16:40:09
Quote Anchor link
Code is "TL;DR" (Too Long, Did not Read).

Je combineert hier ook twee acties: het verwerken van een formulier en het tonen van een formulier. Maak hier beter onderscheid tussen. Bijvoorbeeld door ze in aparte bestanden op te slaan. Maak hierbij gebruik van een Post/Redirect/Get-werkwijze zodat je dubbelposts voorkomt / navigatie vloeiender is.
(eigenlijk combineer je nog meer acties: het toevoegen en verwerken van een toevoeging, en het wijzigen en het verwerken van een wijziging, splits deze bijvoorbeeld op in de acties: add, addProcess, edit, editProcess)

Overweeg het gebruik van sessies.

Ik zie geen foutmeldingen wanneer de informatie die je probeert bij te werken ongeldig is? Ook ben je dan de eerder ingevulde gegevens kwijt? Is niet erg gebruiksvriendelijk.

Ik zie geen token om CSRF te voorkomen.

Escape output ook niet op voorhand, maar pas wanneer het nodig is (vlak voor gebruik/weergave). Dit werkt anders alleen maar verwarrend: je moet terugscrollen om te zien of iets ge-escaped was...

Escape dus niet te vroeg (maar eigenlijk zo laat mogelijk), maar ook alleen voor de huidige context: ben je met SQL bezig en stop je hier DATA in, escape dan je DATA met real_escape_string() maar NIET ook voor de HTML-context (htmlspecialchars). Ben je in de HTML-context bezig en heeft iemand enkel de beschikking over plaintext: gebruik dan bij het weergeven van user data htmlspecialchars() (bij voorkeur met indicatie van character encoding, zie hieronder).

Je document heeft een charset-indicatie, maar deze vergeet je bij het maken van een connectie met je database. Dit is een potentiële bron voor een hoop ellende. Stel altijd expliciet een character encoding in met de set_charset() methode, direct na het maken van een connectie.

Wees je te allen tijde bewust van character encoderingen, het filteren van input en het escapen van output, en vergeet daarbij ook niet te streven naar een soepele(re) gebruikerservaring.
Gewijzigd op 08/02/2017 16:46:39 door Thomas van den Heuvel
 
- Rob -

- Rob -

08/02/2017 16:46:10
Quote Anchor link
Om te voorkomen dat je ingevulde gegevens weg zijn, raad ik AJAX aan. Hiermee post je het naar een ander bestand, zonder dat je pagina gereload wordt.. Verder is het inderdaad verstandig om aparte bestanden te maken voor het formulier, het posten en de database connect (deze heb je hoogst waarschijnlijk op bijna elke pagina nodig, dus dan is het handig als je 1 bestand hebt anders kan je de gegevens op elke pagina aanpassen).
Gewijzigd op 08/02/2017 16:48:06 door - Rob -
 
Thomas van den Heuvel

Thomas van den Heuvel

08/02/2017 16:50:29
Quote Anchor link
- Rob - op 08/02/2017 16:46:10:
Om te voorkomen dat je ingevulde gegevens weg zijn, raad ik AJAX AJAX aan. Hiermee post je het naar een ander bestand, zonder dat je pagina gereload wordt..
Dit is een optie, maar is mogelijk voor een beginner moeilijker te debuggen.

- Rob - op 08/02/2017 16:46:10:
Verder is het inderdaad verstandig om aparte bestanden te maken voor het formulier, het posten en de database connect (deze heb je hoogst waarschijnlijk op bijna elke pagina nodig, dus dan is het handig als je 1 bestand hebt anders kan je de gegevens op elke pagina aanpassen).

Natuurlijk is het handiger om ook includes te hebben voor je database-connectie enzo (of nog beter, een autoloader) maar ik ging er hier eigenlijk vanuit dat dit een standalone script betrof, die ook in afzondering bekeken/behandeld wordt. Als dit formulier deel uitmaakt van een groter systeem zul je inderdaad naar slimmere manieren moeten kijken om je pagina's in elkaar te zetten.
 
Ward van der Put
Moderator

Ward van der Put

08/02/2017 18:25:45
Quote Anchor link
Ik weet niet of het de bedoeling is, maar het script is maar voor één gebruiker geschikt.
Loop maar eens langs wat er met gebruiker-ID 1 gebeurt.
 
Ivo P

Ivo P

09/02/2017 13:12:04
Quote Anchor link
if(!empty($geslacht) == 2)

empty geeft TRUE of FALSE terug.
Met ! keer je dat om naar FALSE of TRUE

En als FALSE/TRUE gelijk is aan 2, dan.....

Idem voor de versie met 1. Als je voor geslacht nog 0 of 1 had gekozen, dan had dit nog wat zinnigs kunnen doen, maar op deze manier lijkt het mij niet te gaan doen wat je wilt.

Toevoeging op 09/02/2017 13:14:07:

En naar de VAn/TOT velden moet je ook nog even kijken.
 
Max PHP

Max PHP

09/02/2017 18:10:28
Quote Anchor link
Ik moet zeggen dat ik zoveel reacties niet had verwacht en uit jullie reacties (waarvoor ik heel dankbaar ben) kan ik alleen maar afleiden dat ik nog veel te leren heb, haha.
Eerlijk gezegd, van wat sommigen van jullie hier zeggen, daar heb ik nog nooit van gehoord en begrijp ik niet. Google helpt soms maar ook niet altijd.

Ik ga met jullie advies wat aanpassingen doen en post het formulier hier dan terug.

- Ariën - op 08/02/2017 15:53:45:
Die stripslashes() zijn verder niet nodig. Waarom zou je die willen strippen?
Als je de boel veilig wilt hebben tegen SQL-injectie, dan is mysqli_real_escape_string() de beste oplossing zolang je de 'ge-escapede' data in de query verwerkt.

Ook raad ik aan om de controle om iets verstuurd te hebben via POST aan te passen naar van
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
    if(isset($_POST['submit'])){


naar:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
if($_SERVER['REQUEST_METHOD'] == "POST") {

Over de stripslashes(), die gebruik ik omdat als ik deze niet gebruik en iets met een enkel of dubbel aanhalingsteken ingeef, ik na submit een backslash krijg voor het enkel of dubbel aanhalingsteken bij de echo.
Op W3schools staat er dit bij stripslashes() "Tip: This function can be used to clean up data retrieved from a database or from an HTML form.".
Ook wordt er hier: http://www.w3schools.com/php/showphp.asp?filename=demo_form_validation_complete in de functie test_input() stripslashes toegepast, deze functie heb ik ook al op veel plaatsen gebruikt zien worden. Daarom dat ik dacht dat het nodig was.

Na wat over $_SERVER['REQUEST_METHOD'] == "POST" gelezen te hebben lijkt het idd beter dan $_POST['submit'].
Ik gebruik altijd $_POST['submit'] omdat ik dit in de meeste voorbeelden en tutorials zie op Engelstalige fora etc. Hier op het forum zie je wel meer $_SERVER['REQUEST_METHOD'] == "POST"

Thomas van den Heuvel op 08/02/2017 16:40:09:
Code is "TL;DR" (Too Long, Did not Read).

Je combineert hier ook twee acties: het verwerken van een formulier en het tonen van een formulier. Maak hier beter onderscheid tussen. Bijvoorbeeld door ze in aparte bestanden op te slaan. Maak hierbij gebruik van een Post/Redirect/Get-werkwijze zodat je dubbelposts voorkomt / navigatie vloeiender is.
(eigenlijk combineer je nog meer acties: het toevoegen en verwerken van een toevoeging, en het wijzigen en het verwerken van een wijziging, splits deze bijvoorbeeld op in de acties: add, addProcess, edit, editProcess)

Overweeg het gebruik van sessies.

Post/Redirect/Get is dus gewoon header('Location: form_security_test.php'); of naar een andere pagina redirecten nadat het form gepost is als ik het goed begrijp? Ik heb het getest en na een pagina refresh wordt idd het formulier niet meer opnieuw gepost.

Ik ga het form wat aanpassen met de dingen die jij hebt genoemd.

Thomas van den Heuvel op 08/02/2017 16:40:09:
Ik zie geen foutmeldingen wanneer de informatie die je probeert bij te werken ongeldig is? Ook ben je dan de eerder ingevulde gegevens kwijt? Is niet erg gebruiksvriendelijk.

Ik heb wel gewoon foutmeldingen hoor, als je iets ongeldigs ingeeft bij het bijwerken. Die worden opgeslagen in een array en met een foreach loop ik ze en toon ze dan in een Bootsstrap alert. De ingevulde gegevens blijven ook staan.

Thomas van den Heuvel op 08/02/2017 16:40:09:
Ik zie geen token om CSRF te voorkomen.

Nog nooit van gehoord, ik ga het opzoeken.

Thomas van den Heuvel op 08/02/2017 16:40:09:
Escape output ook niet op voorhand, maar pas wanneer het nodig is (vlak voor gebruik/weergave). Dit werkt anders alleen maar verwarrend: je moet terugscrollen om te zien of iets ge-escaped was...

Escape dus niet te vroeg (maar eigenlijk zo laat mogelijk), maar ook alleen voor de huidige context: ben je met SQL bezig en stop je hier DATA in, escape dan je DATA met real_escape_string() maar NIET ook voor de HTML-context (htmlspecialchars). Ben je in de HTML-context bezig en heeft iemand enkel de beschikking over plaintext: gebruik dan bij het weergeven van user data htmlspecialchars() (bij voorkeur met indicatie van character encoding, zie hieronder).

Je document heeft een charset-indicatie, maar deze vergeet je bij het maken van een connectie met je database. Dit is een potentiële bron voor een hoop ellende. Stel altijd expliciet een character encoding in met de set_charset() methode, direct na het maken van een connectie.

Wees je te allen tijde bewust van character encoderingen, het filteren van input en het escapen van output, en vergeet daarbij ook niet te streven naar een soepele(re) gebruikerservaring.

Dus:
-Altijd mysqli_real_escape_string() gebruiken als je iets in de database zet of updated?
-Altijd en alleen htmlspecialchars() gebruiken als je iets toont dmv. echo wat een gebruiker heeft ingegeven?
-Altijd na de db connectie: mysqli_set_charset($db_verbinding,"utf8"); zetten?

Is het niet handiger zoals ik het doe, htmlspecialchars() toepassen op alles wat de database ingaat? Dan hoef je het maar één keer te doen en niet overal waar je de output toont?

@-Rob-
Ik weet wat AJAX doet maar ik wil éérst goed genoeg PHP kunnen vooraleer ik me met andere dingen ga bezig houden want anders wordt het wat te veel ineens.
Met verschillende bestanden bedoel je dan alle php code van bovenaan in een ander bestand zetten en dan includen boven het formulier bestand?
Of een bv. verwerk.php maken met de php code en dan bij mijn formulier action"verwerk.php"?
De database verbinding include ik normaal wel altijd op pagina's waar een verbinding is vereist.

Ward van der Put op 08/02/2017 18:25:45:
Ik weet niet of het de bedoeling is, maar het script is maar voor één gebruiker geschikt.
Loop maar eens langs wat er met gebruiker-ID 1 gebeurt.

Is idd maar voor 1 gebruiker. Anders zou ik de 1 vervangen door een variabel waar de id in zit, die id zou dan vanuit de url of een session komen denk ik. Dat weet ik ook nog niet juist hoe zoiets juist werkt.

@Ivo P
Dank je. Man bleef altijd checked idd, ik heb het aangepast.
Bij de checkbox van de nieuwsbrief was het ook fout.

De van/tot lijkt na onderstaande aanpassingen goed te werken. Of bedoel je iets anders?
Ik heb ik de 2 elseif aangepast naar:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
<?php
elseif(!empty($_POST['van']) && empty($_POST['tot'])){
            $errors[] = "Van en tot zijn beide verplicht als je ze niet leeg laat!";
            $van = $_POST['van'];
            $tot = "11:11:11";
        }
elseif(empty($_POST['van']) && !empty($_POST['tot'])){
            $errors[] = "Van en tot zijn beide verplicht als je ze niet leeg laat!";
            $van = "11:11:11";
            $tot = $_POST['tot']
?>

en de dropdowns naar:
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
<div class="col-sm-5 col-md-4 col-lg-4">
                                    <select class="form-control" name="van" id="beschikbaar">
                                        <option value=""<?php if(isset($van) && $van == "11:11:11"){ echo " selected";} ?>>- Van -</option>
                                        <option value="00"<?php if(isset($van) && $van == "00:00:00" || $van == "00"){ echo " selected";} ?>>00u00</option>
                                        <option value="1"<?php if(isset($van) && $van == 1){ echo " selected";} ?>>01u00</option>
                                        <option value="23"<?php if(isset($van) && $van == 23){ echo " selected";} ?>>23u00</option>
                                    </select>
                                </div>
                                <p class="col-sm-2 text-center">tot</p>
                                <div class="col-sm-5 col-md-4 col-lg-4">
                                    <select class="form-control" name="tot" id="m">
                                        <option value=""<?php if(isset($tot) && $tot == "11:11:11"){ echo " selected";} ?>>- Tot -</option>
                                        <option value="00"<?php if(isset($tot) && $tot == "00:00:00" || $tot == "00"){ echo " selected";} ?>>00u00</option>
                                        <option value="1"<?php if(isset($tot) && $tot == 1){ echo " selected";} ?>>01u00</option>
                                        <option value="23"<?php if(isset($tot) && $tot == 23){ echo " selected";} ?>>23u00</option>
                                    </select>
                                </div>


Ik moet zeggen dat dit forum wel wat moeilijker te gebruiken is dan de meeste andere fora. Geen multiquote etc.
 
- Ariën  -
Beheerder

- Ariën -

09/02/2017 18:42:38
Quote Anchor link
Quote:
Is het niet handiger zoals ik het doe, htmlspecialchars() toepassen op alles wat de database ingaat? Dan hoef je het maar één keer te doen en niet overal waar je de output toont?

Nee, je wilt je data immers niet verminken. Stel dat je dan Jip & Janneke in de database zet, dan wordt dat dus automatisch: Jip &amp; Janneke

Wil je dat? Dus als je een onderwerp met deze string wilt zoeken, dan zal je niks vinden.
Als je het op de output toepast, dan blijft de bron netjes behouden.
 
- Rob -

- Rob -

09/02/2017 19:54:12
Quote Anchor link
Volgensmij heeft niemand dit nog gezegt; is het niet handig om je SQL te controleren of die klopt? En of hij geen lege waardes terug geeft? Ik zou hier ook nog even naar kijken, zodat er niet onnodige code wordt gerund met een foute query
 
- Ariën  -
Beheerder

- Ariën -

09/02/2017 19:58:04
Quote Anchor link
Bij de eerste query mist dit, maar verder wordt het wel daarna structureel toegepast. Wel zou ik dan geen technische en vitale data teruggeven naar de gebruiker. Een gebruiker boeit bijvoorbeeld weer niks dat 'het aantal kolommen niet matched met de values, of dat een tabel niet bestaat. En hackers moet je ook niet teveel wijsmaken over de werking van je site ;-)

Meld dan gewoon dat er fout op de website is, en de beheerders op de hoogte worden gebracht. Log de fout dan netjes in een logbestand. Foutmeldingen zijn wel weer leuk voor websites die in ontwikkeling zijn. Daarom kan je een controle op de URL bouwen, of een configuratieoptie bouwen om queries en foutmeldingen te tonen.
Gewijzigd op 09/02/2017 20:03:00 door - Ariën -
 



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.