PHP scripts
Gastenboek
Niveau: Beginner
PHP versie: *
Categorie: Gastenboeken/Fora
Toelichting:
Ik hoor je denken, alweer een gastenboek. Ja, weer een gastenboek. Ik heb dit gastenboek gemaakt om te kijken of het goed gescript is en of iemand er iets mee kan. De beveiliging is volgens mij wel goed.
Getest op:
- XSS Injection;
- SQL Injection;
- Velden niet ingevuld;
- Spam interval
De bovenstaande dingen zijn beveiligd om ervoor te zorgen dat bezoekers geen rotzooi uithalen met je website. De gegevens worden gefilterd opgeslagen in de database, en er wordt stripslashes() en htmlspecialchars() gebruikt om ze te weergeven.
Alles werkt op 1 pagina, je zit dus niet met gedoe met meerdere pagina's.
Wijzingingen
27 maart 2009:
- Gegevens worden gefilterd de database ingezet;
- Maximaal aantal karakters toegevoegd;
- MySQL errors verwijderd, hij geeft nu niet de error zelf;
- Tekst veranderen als er op de knop gedrukt wordt.
28 maart 2009:
- Berichten pas filteren bij het ophalen (dankzij Bas Kreleger);
- Betere beveiliging voor lege velden.
3 april 2009:
- Er is nu ook een interval toegevoegd.
17 mei 2009:
- Maxlength toegevoegd bij naam;
- UBB parser toegevoegd.
5 september 2009:
- XHTML 1.1 gevalideerd;
- Alles stukken sneller gemaakt;
- Foutafhandeling ingebouwd;
- Meerdere lijnen worden nu ondersteund.
16 september 2009:
- Tekst opmaak fout opgelost;
- IP-adres wordt nu ook beveiligd;
- Alles wordt nu geregeld voordat de gebruiker wat te zien krijgt;
- Spam interval verwijderd en vervangen door een niet-waterdichte spamfilter. *
17 oktober 2009:
- Berichten sorteren gaat nu op datum.
Rate & Comment :)
* Let op: deze beveiliging is niet optimaal veilig. Een niet al te simpele spambot gaat hier gewoon doorheen.
SQL Code:
|
1 2 3 4 5 6 7 8 |
CREATE TABLE `gastenboek` ( `id` int(11) NOT NULL auto_increment, `naam` varchar(16) NOT NULL default '', `bericht` text NOT NULL, `datum` datetime NOT NULL default '0000-00-00 00:00:00', `ip` varchar(15) NOT NULL default '', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ; |
Code gastenboek:
|
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 |
<?php error_reporting(E_ALL); $host = ""; // Je host $user = ""; // Je MySQL gebruikersnaam $pass = ""; // Je MySQL wachtwoord $datb = ""; // Je MySQL database // Verbinding maken mysql_connect($host, $user, $pass) or die ("Er is iets mis gegaan"); mysql_select_db($datb) or die ("Er is iets mis gegaan"); // UBB aanmaken function ubb($string) { $string = htmlspecialchars($string); // Beveiligen voor XSS injection $string = stripslashes($string); // Slashes verwijderen $string = nl2br($string); // Zorgen dat er meerdere regels gebruikt kunnen worden $string = preg_replace("#\[b\](.+?)\[/b\]#is", "<b>\\1</b>", $string); // [b][/b] => <b></b> $string = preg_replace("#\[i\](.+?)\[/i\]#is", "<i>\\1</i>", $string); // [i][/i] => <i></i> $string = preg_replace("#\[u\](.+?)\[/u\]#is", "<u>\\1</u>", $string); // [u][/u] => <u></u> $string = preg_replace("#\[s\](.+?)\[/s\]#is", "<s>\\1</s>", $string); // [s][/s] => <s></s> return $string; } $dagen = Array("zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Gastenboek - Gemaakt door Roel</title> </head> <body> <h1>Reactie plaatsen</h1> <?php if ($_SERVER['REQUEST_METHOD'] == 'POST') { // Als er een veld niet ingevuld is if (empty($_POST['naam']) || empty($_POST['bericht'])) { echo '<span style="color:red; font-weight: bold">Je hebt niet alle velden ingevuld!</span>'; } elseif (strlen($_POST['naam']) > 16 || strlen($_POST['bericht']) > 500) { echo '<span style="color:red; font-weight: bold">De ingevulde velden hebben te veel karakters (naam maximaal 16, bericht maximaal 500)</span>'; } elseif ($_POST['dag'] != $dagen[date('w')]) { echo '<span style="color:red; font-weight: bold">De ingevulde dagnaam klopt niet!</span>'; } else { // Als alle velden ingevuld zijn wordt het bericht gefilterd toegevoegd if (mysql_query("INSERT INTO gastenboek (naam, bericht, datum, ip) VALUES ('".trim(mysql_real_escape_string($_POST['naam']))."', '".trim(mysql_real_escape_string($_POST['bericht']))."', NOW(), '".mysql_real_escape_string($_SERVER['REMOTE_ADDR'])."')")) { echo '<span style="color:green; font-weight: bold"Je reactie is succesvol toegevoegd!</span>'; } else { echo '<span style="color:green; font-weight: bold">Er is iets fout gegaan en je reactie is niet toegevoegd. Probeer het later opnieuw.</span>'; } } } ?> <form method="post" action=""><p> Naam: (maximaal 16 karakters)<br /> <input type="text" name="naam" maxlength="16" /><br /><br /> Welke dag is het vandaag:<br /> <input type="text" name="dag" /><br /><br /> Bericht: (maximaal 500 karakters)<br /> <textarea name="bericht" id="tekst" rows="6" cols="37"></textarea><br /><br /> <input type="submit" value="Toevoegen" onclick="this.value='Reactie wordt geplaatst...';" /> <input type="reset" value="Herstel" /> </p></form> <hr /> <p> <?php // Gegevens ophalen uit de database en sorteren op id $sql = mysql_query("SELECT * FROM gastenboek ORDER BY datum DESC"); if (mysql_num_rows($sql) == 0) { // Als er nog geen reacties geplaatst zijn echo 'We hebben nog geen reacties!'; } else { while($data = mysql_fetch_assoc($sql)) { // Als er wel reacties zijn geplaatst worden deze nu weergegeven echo '<b>Naam:</b> '.htmlspecialchars(stripslashes($data['naam'])).'<br /> <b>Datum:</b> '.htmlspecialchars(stripslashes($data['datum'])).'<br /> <b>Bericht:</b><br />'.ubb($data['bericht']).'<br /><br />'; } } ?> </p> </body> </html> |
Code:
Zie bovenstaande code, dit omdat HTML codes anders buiten het code veld staan.
Meer PHP scripts in deze categorieReacties
Voeg ook een reactie toe.
Waarom nou geen mysql_real_escape_string()???
Kijk naar de query, daar filter ik de gegevens pas.
idd zoals roel zegt..... waarom bij het weergeven nogmaals checken op xss/sql injection als je bij de insert dit al goed doet hoeft je dat niet meer te doen.
De tip: Check vooraf wat er de database ingaat niet wat je GB moet uitspugen.
bijvoorbeeld door:
|
1 2 3 |
<?php $name = trim(htmlspecialchars($_POST["Name"])); ?> |

Gewijzigd op 26.03.2009 20:16 door Martijn van Boxtel
Wel 55 regels code, waarvan de helft html en nog eens een groot deel configuratie.. Hier hebben we weer veel aan.
vrij standaard, maar miss ff checken of de naam niet langer dan 16 tekens is, want mysql vindt het geen probleem om iets wat langer dan 16 tekens is in een daarvoor bestemt veld te gooien (de rest verdwijnt gewoon), dus moet jij zelf die controle maar uitvoeren..
Zolang het script een zwanendood sterft bij het mislukken van een query, is het niet echt bruikbaar. Voor het gemak ook nog even de foutmelding op het scherm gooien is leuk voor hackers en handig tijdens het bouwen en testen, maar niet wanneer de boel live moet.
Verder mag de nl2br() op regel 26 nog even richting prullenbak, je gaat geen html in de database zetten. html maak je aan wanneer je html richting browser wilt sturen en een database is géén browser.
En verder, tja, ,13 in een dozijn script.
Waarom nl2br() gebruiken om het in je database te schrijven, doe dat bij het er uit halen.
\n is minder bytes dan <br />
Verder, hoeveel gastenboeken zijn er inmiddels al? Ook is valid xHTML leuk ^^
Goede manier van foutafhandeling :-).
*sarcasm* 8-|
Het ziet er wel lekker overzichtelijk uit, maar qua inhoud kan het nog vele malen beter. Bijv. sorteren op een id doen we niet, daar gebruiken we data voor. Nog eens logischer ook. En mysql_fetch_assoc() is veel sneller dan mysql_fetch_array(). En doe nog wat aan die foutafhandeling!!!
Ziet er goed uit ;]
Mischien handig om een limiet te maken?
5 berrichten weergeven [scrolbar]?
1 berricht per 5 minuten?
miss stripslashes() gebruiken ??
en controleren met captcha... (ivm cURL)
en ook een soort floodcontrol (dus een soort cookie, die controleert of je niet al eerder hebt gepost binnen een bepaalde tijd...)
ook een bepaald tekst limiet, zodat je niet een overdreven lang bericht krijgt van 60.000 tekens of meer...
zelf vind ik <strong> ook beter dan <b> (geen idee waarom)
|
1 |
or die ("<b>Fout:</b> ".mysql_error()
|
verder zou ik er ook smileys bij doen.
dat was het wel ;)
Zet
error_reporting(0);
boven aan de pagina wel na <?php
;)

Gewijzigd op 27.03.2009 13:32 door Mike
Ik zie dat je de data htmlspecialchars() meegeeft de database in. Ik kies hier zelf eigenlijk nooit voor zodat je data zoals het geschreven is in de database staat en je er bij het eruit halen er mee kunt doen wat je wilt. Waarom heb je hier voor gekozen?
Tja eigenlijk weet ik dat zelf ook niet echt. Misschien omdat als ik de database ergens anders voor wil gebruiken dat ie dan in ieder geval veilig is, een betere reden kan ik eigenlijk niet bedenken.
Spamvrij?
welke grapjurk heeft hier cURL gebruikt ;P
(hier had ik eerder ook al iets over gezecht :P)

Gewijzigd op 02.04.2009 20:09 door Johnny Bravo
Bij het plaatsen van het bericht moet je ook nog even met interval werken. Op deze manier kan je bijvoorbeeld maar 1 keer per dag posten per IP.
Voorbeeld:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php $query = mysql_query("SELECT id FROM gastenboek WHERE ip = '".mysql_real_escape_string($_SERVER['REMOTE_ADDR'])."' AND datum >= NOW() - INTERVAL 1 DAY"); if($query) { if(mysql_num_rows($query) > 0) { die('Je mag maar 1 keer per dag posten!'); } } else { echo '<p>Error' . mysql_error() . '</p>'; } ?> |

Gewijzigd op 02.04.2009 22:01 door Marcel
lekkere spam blok:p
je hebt staan: Berichten pas filteren bij het ophalen (dankzij Bas);
gaat dat over mij of een andere bas
Nee, over Bas Kreleger. :P
Damn, m'n spambot gaat niet meer :p.. Goed gevonden dat 1 bericht per 24 u ;)
Bedank Marcel daar liever voor XD
@ Roel : Leuk gedaan en nu de smilies erin :-)
Graag gedaan^^
handig zeg dat je 1 bericht per 24 uur kan posten :|, doe er dan gewoon een goede CAPTCHA bij ipv dit soort dingen die vervelend worden voor regelmatige posters.
Daar is een gastenboek niet echt voor bedoeld.
remie schreef op 17.05.2009 16:58
handig zeg dat je 1 bericht per 24 uur kan posten :|, doe er dan gewoon een goede CAPTCHA bij ipv dit soort dingen die vervelend worden voor regelmatige posters.
Of je pakt gewoon een proxy....
Wat ik mij nu wel afvraag is hoe meerdere mensen met hetzelfde ip (neem een school) een bericht kan posten. Dat kan namelijk nu niet.
Dat is dus harstikke fout.

Gewijzigd op 18.05.2009 16:48 door Karl
Als ik er een captcha bij moet doen is de code van de captcha groter dan de code van het gastenboek.
Nou en ? Het is gebruiksvriendelijker dan 24 uur wachten. Dat is toch waar het uiteindelijk om draait ? De gasten die het gastenboek gebruiken, niet jij met je script
hoe zorg ik ervoor dat mensen vaker dan 1 keer per dag kunnen reageren?
|
1 2 3 |
$sql = mysql_query("SELECT * FROM gastenboek WHERE ip = '".mysql_real_escape_string($_SERVER['REMOTE_ADDR'])."' AND datum >= NOW() - INTERVAL 1 DAY"); if (mysql_num_rows($sql) == 0) { |
en
|
1 2 3 |
} else { echo 'Je hebt vandaag al een reactie geplaatst. Je moet tot morgen wachten om een nieuwe reactie te plaatsen.'; } |
eruit halen.
Ja of je zet gewoon // voor iedere regel daar.
Ok bedankt!! Het is gelukt!
Ik heb gewoon INTERVAL 1 DAY veranderd in INTERVAL 5 MINUTE
Ik heb alleen wel nóg een vraag, opmerking... Als ik om 22:28 een bericht invul komt er als tijd 20:19 te staan! Hoe komt dat? Doe ik iets verkeerd? Ik hoop het toch niet!

Gewijzigd op 13.09.2009 23:05 door Joeri
Dan staat de server tijd anders dan bij jou op de computer.
ik ben niek61 en ik ben wie ik ben, maar geen Bas Kreleger
hoe kan dit
PS.
23.05 uur
ik ben geen hacker. maar toen ik vandaag mijn pc had opgestart en naar deze site ging stond ik wel als zodanig ingelogd, maar als ik naar mijn gevens kijk kloppen behalve de inlognaam de andere gegevens wel.
23.12 uur
heb me uitgelogd en opnieuw ingelogd maar resultaat blijft het zelfde

Gewijzigd op 05.02.2010 23:12 door Bas Kreleger
Voeg een reactie toe
Alleen leden mogen reacties toevoegen. Dit i.v.m. het vele spam die we de laatste tijd hebben gekregen. Je kunt je registreren op de registratie pagina. Ben je al lid? Dan kun je inloggen aan de bovenkant van de website.
Ga naar het overzicht met PHP scripts.
