Hallo zusammen,
bitte vergebt mir falls ich hier in einen falschen Thread posten sollte, aber ich bin ganz neu hier.
Hab mich die letzen Wochen und Monate ein wenig in PHP eingelesen, und hab jetzt ein kleines simples Gästebuch (PHP, MySQL) geschrieben und wollte das mit nem CAPTCHA schützen... mangels meiner Kenntnisse in GD hab ich das ganze OHNE GD gelöst und wollt die erfahrenen PHPler fragen, ob sie Sicherheitsbedenken oder sonstige Tipps haben...
um wir jetzt das posten des MySQL-Codes zu sparen kurz vorweg.
das ganze funzt mit 3 Tabellen
1. Tabelle: captcha
Felder: cid, wert, bild
beispiel: cid: 2, wert: b, bild= öakldfjöadklfjadlf.gif (in dem bild wird ein b angezeigt)
2. Tabelle: c_pruefung
Felder: cpid, wert_gen, ip, timestamp
Beispiel cpid: 1, wert_gen: b2nov, ip: 1.2.3.4, timestamp: 2146468
3. Tabelle: gb_eintr
Felder: name, email, nachricht, datenschutz
...
Funktionieren tut das ganze natürlich nur, wenn man vorher entsprechende Bilder in ein Verzeichnis (zb. img) laedt und ihnen erstmal einen default-Namen gibt (z.B. a.gif), und die auch so in die Datenback verlinkt also in der Tabelle captcha wert: a bild: a.gif. bei jedem aufruf der seite wird den bilder ein neuer md5-verschlüsselter name zugewiesen...
So und hier der Code:
PHP-Code:
<?php
// Hostname oder IP des MySQL-Servers
$sqlhost = "localhost";
// Username und Passwort
$sqluser = "*******";
$sqlpassword = "*******";
// Name der Datenbank
$sqldb = "*********";
// Verbindung herstellen
mysql_connect($sqlhost,$sqluser,$sqlpassword) or die ("Keine Verbindung möglich"); mysql_select_db($sqldb) or die ("Die Datenbank existiert nicht");
function createc () {
#neue Bildnamen generieren
$def_query = mysql_query("SELECT * FROM captcha");
while ($oldname = mysql_fetch_array($def_query, MYSQL_ASSOC))
{$timestamp = time();
$newbild = md5($oldname['wert']."_".$timestamp).".gif";
$wert = $oldname['wert'];
mysql_query("UPDATE captcha SET bild='$newbild' WHERE wert='$wert'");
rename("img/".$oldname['bild']."", "img/".$newbild."")
;}
# CAPTCHA
# 5 Zufallswerte, die Werte müssen als cid (Captcha-ID) in der Datenbank vorhanden sein<br />
# dh. bei 29 möglichen Buchstaben muss der Max-Wert 29 sein.
$b1 = rand(1,29);
$b2 = rand(1,29);
$b3 = rand(1,29);
$b4 = rand(1,29);
$b5 = rand(1,29);
# Suche die Einträge aus der Datenbank
$cresult1 = mysql_query("SELECT * FROM captcha WHERE cid='$b1'");
$cresult2 = mysql_query("SELECT * FROM captcha WHERE cid='$b2'");
$cresult3 = mysql_query("SELECT * FROM captcha WHERE cid='$b3'");
$cresult4 = mysql_query("SELECT * FROM captcha WHERE cid='$b4'");
$cresult5 = mysql_query("SELECT * FROM captcha WHERE cid='$b5'");
$bild1 = mysql_fetch_array($cresult1, MYSQL_ASSOC);
$bild2 = mysql_fetch_array($cresult2, MYSQL_ASSOC);
$bild3 = mysql_fetch_array($cresult3, MYSQL_ASSOC);
$bild4 = mysql_fetch_array($cresult4, MYSQL_ASSOC);
$bild5 = mysql_fetch_array($cresult5, MYSQL_ASSOC);
#Gib die entsprechenden Bilder aus...
echo "
<br />
<div id=\"captcha\" class=\"captcha\"><img src=\"img/$bild1[bild]\" width=\"30\" height=\"30\" /><img src=\"img/$bild2[bild]\" width=\"30\" height=\"30\" /><img src=\"img/$bild3[bild]\" width=\"30\" height=\"30\" /><img src=\"img/$bild4[bild]\" width=\"30\" height=\"30\" /><img src=\"img/$bild5[bild]\" width=\"30\" height=\"30\" /></div>";
#generiere die Zeichenfolge und schreib sie in die Tabelle c_pruefung zum Abgleich
#loesche alle Einträge, die älter sind als 5 Min. für den jeweiligen User und alle übrigen, die älter sind als 1 Std.
$werte = "".$bild1['wert']."".$bild2['wert']."".$bild3['wert']."".$bild4['wert']."".$bild5['wert']."";
$ipadresse = $_SERVER['REMOTE_ADDR'];
$timestamp = time();
$minus5min = $timestamp - 300;
$minus1std = $timestamp - 3600;
mysql_query("INSERT INTO c_pruefung (wert_gen, ip, timestamp) VALUES ('$werte', '$ipadresse', '$timestamp');");
mysql_query("DELETE FROM c_pruefung WHERE timestamp < '$minus5min' AND ip='$ipadresse'");
mysql_query("DELETE FROM c_pruefung WHERE timestamp < '$minus1std'");
}
#Eingabe überprüfen
#bei mehr als 3 Falschen angaben wird der User für 5 Min gesperrt.
#wenn richtig wird die Flag $captcha=1 ausgegeben
function pruefen () {
if (isset($_POST['csend'])) {
$ipadresse = $_SERVER['REMOTE_ADDR'];
$pruefen = htmlspecialchars(strtolower($_POST['pruefen']));
$pcount = mysql_query("SELECT * FROM c_pruefung WHERE ip='$ipadresse'");
$panzahl = mysql_num_rows($pcount);
if ($panzahl > 3) {$captcha = "0"; echo "Du bist 5 Minuten gesperrt!"; exit;
;}
else {
$pquery = mysql_query("SELECT * FROM c_pruefung WHERE ip='$ipadresse' AND wert_gen='$pruefen' LIMIT 0,1");
$presult = mysql_fetch_array($pquery, MYSQL_ASSOC);
if (!empty($presult['wert_gen'])) {$captcha = "1";
mysql_query("DELETE FROM c_pruefung WHERE ip='$ipadresse'");
;}
else {$captcha = "0"; echo "Bitte geben Sie den Sicherheitscode korrekt ein."; exit;
;}
;}
;}
;}
#Eintrag ins Gästebuch, wenn $captcha 1 ist
#Man kann auswählen, ob die E-Mail angezeigt werden soll oder nicht...
function guestbook ($captcha) {
if (isset($_POST['csend'])) {
if ($captcha = "0") {echo "Eingabe Fehlgeschlagen!";}
if ($captcha = "1") {
$name = htmlspecialchars($_POST['name']); $email = htmlspecialchars($_POST['email']);
$bb = htmlspecialchars($_POST['nachricht']);
$eingabe= array ("[b]", "[/b]");
$ausgabe= array ("<b>","</b>");
$nachricht= nl2br(str_replace($eingabe, $ausgabe, $bb));
if ($_POST['ds'] == "ja") {$ds = "ja";}
else {$ds = "nein";}
mysql_query("INSERT INTO gb_eintr (name, email, nachricht, datenschutz) VALUES ('$name','$email','$nachricht', '$ds');");
echo "<script>window.location='captcha.php'</script>";
;}
;}
;}
#Ausgabe der Einträge, mit dem neuesten zuerst...
function eintr_ausgabe () {
$ausgabeerg = mysql_query ("SELECT * FROM gb_eintr ORDER BY eid DESC");
while ($gb = mysql_fetch_array($ausgabeerg, MYSQL_ASSOC))
{echo "Name: $gb[name]<br>";
if ($gb['datenschutz'] == "ja") {echo "Email: $gb[email]<br>";}
else {echo "";}
echo "Nachricht: $gb[nachricht]<br>
<hr>";
;}
;}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Unbenanntes Dokument</title>
<style type="text/css">
<!--
.captcha {
border: 1px solid #000000;
height: 30px;
width: 150px;
}
-->
</style>
</head>
<body>
<form id="form1" name="form1" method="post" action="<?php $_SERVER['PHP_SELF'];?>">
<input type="text" name="name" id="name" value="<?php echo $_POST['name']; ?>" /><br />
<input type="text" name="email" id="email" value="<?php echo $_POST['email']; ?>" /><br />
<textarea name="nachricht" rows="10" id="nachricht"><?php echo $_POST['nachricht']; ?></textarea>
<br />
<input name="ds" type="checkbox" id="ds" value="ja" />
E-Mail anzeigen<br />
<br />
<?php createc (); ?>
<input type="text" name="pruefen" id="pruefen" /> <input type="submit" name="csend" id="csend" value="Senden" />
<br />
<?php pruefen (); echo " "; guestbook($captcha); ?><br />
<br />
<br />
<br />
<br /><?php eintr_ausgabe() ;?>
</form>
</body>
</html>
Wie das ganze dann in der Praxis aussieht? So: Test-Gästebuch