seVes: Bots flooden Gästebuch trotz CAPTCHA?

Servus!

Ich hab das Gästebuch auf Klick entwickelt und bin etwas schockiert darüber, dass es Bots schaffen, sich dort einzutragen, obwohl ich Captcha nutze. Die müssen ja dann auf das Bild irgendwie zugreifen können? Ich versteh das nicht...

guestbook.php

<?php  
	require("./content/dbconfig.php");  
	$connected=mysql_connect($host, $username, $password);  
	if(@$connected){  
		include("./content/news.php");  
		mysql_select_db($database, $connected);  
		$rows_per_page=15;  
		$page_number=1;  
		if(isset($_GET['show'])){  
			$page_number=$_GET['show'];  
		}  
		$offset=($page_number-1)*$rows_per_page;  
		echo '  
			<div id="content">  
				<h2>Gästebuch</h2>  
				<br><a href="javascript:show(\'guestbook_write\');">Gästebucheintrag schreiben</a><br><br>  
				<div id="guestbook_write" style="display: none;">  
					<form action="./index.php?page=guestbook&amp;send=guestbook" method="post">  
						<div class="formleft">  
							Name<font color="#C71E23">*</font>:<br>  
							<input class="form" type="text" name="name" value="'.$_POST["name"].'" size="30" maxlength="40"><br><br>  
							E-Mail-Adresse:<br>  
							<input class="form" type="text" name="email" value="'.$_POST["email"].'" size="30" maxlength="40"><br><br>  
							Website:<br>  
							<input class="form" type="text" name="website" value="'.$_POST["website"].'" size="30" maxlength="40">  
						</div>  
						<div class="formright">  
							Club:<br>  
							<input class="form" type="text" name="club" value="'.$_POST["club"].'" size="31" maxlength="40"><br><br>  
							Sicherheitscode<font color="#C71E23">*</font>:<br>  
							<input class="form" type="text" name="security" size="31" maxlength="40"><br><br>  
							<img src="./content/captcha.php" title="Sicherheitscode" alt="Sicherheitscode" height="40px" width="140px"><br>&nbsp;  
						</div>  
						<div class="formbottom">  
							Nachricht<font color="#C71E23">*</font>:<br>  
							<textarea class="form" name="message" rows="5" cols="56">'.$_POST["message"].'</textarea><br><br>  
							<input class="button" type="submit" name="submit_guestbook" value="Absenden">&nbsp;  
							<input class="button" type="reset" name="reset_guestbook" value="Abbrechen"><br><br>  
						</div>  
						<i>Die mit <font color="#C71E23">*</font>-gekennzeichneten Felder müssen ausgefüllt werden!</i>  
					</form>  
				</div>';  
		$result1=mysql_num_rows(mysql_query('SELECT id from guestbook'));  
		$max_pages=ceil($result1/$rows_per_page);  
		$self=$_SERVER['PHP_SELF'];  
		$nav="";  
		for($page=1; $page<=$max_pages; $page++){  
			if($page==$page_number){  
				$nav.=''.$page.' ';  
			}else{  
				$nav.='<a href="./index.php?page=guestbook&show='.$page.'">'.$page.'</a> ';  
			}  
		}  
		if($page_number>1){  
			$page=$page_number-1;  
			$prev='<a href="./index.php?page=guestbook&show='.$page.'">&lsaquo;</a> ';  
			$first='<a href="./index.php?page=guestbook&show=1">&laquo;</a> ';  
		}else{  
			$prev='';  
			$first='';  
		}  
		if($page_number<$max_pages){  
			$page=$page_number+1;  
			$next='<a href="./index.php?page=guestbook&show='.$page.'">&rsaquo;</a> ';  
			$last='<a href="./index.php?page=guestbook&show='.$max_pages.'">&raquo;</a> ';  
		}else{  
			$next='';  
			$last='';  
		}  
		$result2=mysql_query('SELECT DATE_FORMAT(date, "%d.%m.%Y %H:%i") AS date, name, email, website, club, message FROM guestbook ORDER BY id DESC LIMIT '.$offset.', '.$rows_per_page.'');  
		while($row=mysql_fetch_array($result2)){  
			$date=$row['date'];  
			$name=$row['name'];  
			$email=$row['email'];  
			$website=$row['website'];  
			$club=$row['club'];  
			$message=$row['message'];  
			$infos="";  
			if(trim($email)!=""){  
				$infos.='<a href="mailto:'.$email.'"><img src="./media/email.gif" alt="Email" title="Email"></a>';  
			}			  
			if(trim($website)!=""){  
				$infos.='&nbsp;<a href="'.$website.'" target="_blank"><img src="./media/website.gif" alt="Website" title="Website"></a>';  
			}  
			$infos.='&nbsp;'.$date.'';  
			echo '  
				<div class="guestbook_entry">  
					<div class="infos">'.$infos.'</div>  
					<div class="name">'.$name.'</div>  
					<div class="club">'.$club.'</div>  
					<div class="message">'.$message.'</div>								  
				</div>';  
		}  
		echo '  
				'.$first.$prev.$nav.$next.$last.'  
			</div>  
		</div>';  
		mysql_close($connected);  
	}else{  
		echo '  
		<div id="infoheadline">  
			Beim Verbinden mit der Datenbank ist ein Fehler aufgetreten.  
		</div>  
		<div id="infomessage">  
			Bitte kontaktieren Sie schnellstmöglich den Webmaster!<br><br>Vielen Dank.  
		</div>';  
		include("./content/contact.php");  
	}  
?>

send.php

}elseif(($_GET['send']="guestbook") && isset($_POST['submit_guestbook'])){  
  
		$name=$_POST['name'];  
		$email=strtolower($_POST['email']);  
		$website=$_POST['website'];  
		$message=$_POST['message'];  
		$security=$_POST['security'];  
		$club=$_POST['club'];  
		$date=date("Y-m-d H:i:s");  
		  
		if(trim($name)==""){  
			$missing.="Bitte geben Sie ihren Namen an.<br>";  
		}  
		if(!ereg("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,6})$",$email) && $email!=""){  
			$missing.="Bitte geben Sie eine gültige E-Mail-Adresse an! (Bsp.: max.mustermann@domain.de)<br>";  
		}  
		if(!ereg("^(http://|https://)(([a-z0-9]([-a-z0-9]*[a-z0-9]+)?){1,63}\.)+[a-z]{2,6}$",$website) && $website!=""){  
			$missing.="Bitte geben Sie eine gültige Website an! (Bsp.: http://www.domain.de)<br>";  
		}  
		if(trim($message)==""){  
			$missing.="Bitte geben Sie eine Nachricht ein.<br>";  
		}  
		if(trim($security)==""){  
			$missing.="Bitte geben Sie den angezeigten Sicherheitscode an.";  
		}  
		if(isset($_SESSION['captcha_spam']) && (trim($security)!="") && (trim($security)!=$_SESSION['captcha_spam'])){  
			$missing.="Der eingegebene Sicherheitscode ist nicht korrekt!<br>Bitte geben Sie den unten stehenden Sicherheitscode ein."; 	  
		}  
		  
		if(isset($missing)){  
			unset($_SESSION['captcha_spam']);  
			echo '  
		<div id="infoheadline">  
			Bitte korrigieren Sie folgende Angaben:  
		</div>  
		<div id="infomessage">  
			'.$missing.'  
		</div>';  
			include("./content/guestbook.php");  
		}else{  
			if($club==""){  
				$club="-";  
			}  
			$connected=mysql_connect($host, $username, $password);  
			if(@$connected){  
				unset($_SESSION['captcha_spam']);  
				mysql_select_db($database, $connected);  
				$result=mysql_query('INSERT INTO guestbook (id, date, name, email, website, club, message) VALUES (NULL, "'.$date.'", "'.$name.'", "'.$email.'", "'.$website.'", "'.$club.'", "'.nl2br($message).'")');  
				unset($_SESSION['captcha_spam']);  
				if(@$result){  
					echo '  
		<div id="infoheadline">  
			Vielen Dank für Ihren Gästebucheintrag.  
		</div>  
		<div id="infomessage">  
			Ihr Eintrag sollte in den nächsten Sekunden im Gästebuch sichtbar sein.	  
		</div>';  
				}else{  
					echo '  
		<div id="infoheadline">  
			Beim Erstellen Ihres Gästebucheintrages ist ein Fehler aufgetreten.  
		</div>  
		<div id="infomessage">  
			Bitte kontaktieren Sie schnellstmöglich den Webmaster!<br><br>Vielen Dank.  
		</div>';  
				}  
				include("./content/guestbook.php");  
			}else{  
				unset($_SESSION['captcha_spam']);  
				echo '  
		<div id="infoheadline">  
			Beim Verbinden mit der Datenbank ist ein Fehler aufgetreten.  
		</div>  
		<div id="infomessage">  
			Bitte kontaktieren Sie schnellstmöglich den Webmaster!<br><br>Vielen Dank.  
		</div>';  
				include("./content/contact.php");  
			}  
		}  
	}

Findet irgendjemand da irgendwie eine Lücke? Bin echt ratlos...

Dankeschön! :-)

--
Mit freundlichen Grüßen
seVes

  1. Namaste,

    Ich hab das Gästebuch auf Klick entwickelt und bin etwas schockiert darüber, dass es Bots schaffen, sich dort einzutragen, obwohl ich Captcha nutze. Die müssen ja dann auf das Bild irgendwie zugreifen können? Ich versteh das nicht...

    Das Captcha, was du verwendest kann sehr leicht per OCR eingelesen werden. Captchas müssen, wenn sie den funktionieren sollen so gestalltet werden, dass sie eben nur schwer per OCR erfasst werden können (Ein einfacher Farbverlauf reicht da nicht). Das führt allerdings auch dazu, dass sie von Menschen oft auch nur schwer zu entziffern sind womit wir schon bei den Nachteilen wären.

    thebach

    --
    selfcode: ie:% fl:( br:> va:) ls:& rl:( n4:~ ss:| de:> js:( ch:? mo:} zu:)
    "Egal, ob ein Sandkorn oder ein Stein. Im Wasser sinken sie beide."
  2. hi,

    Findet irgendjemand da irgendwie eine Lücke? Bin echt ratlos...

    Eine hätte ich: Deine Session-ID ist auch nach shift-reload immer noch diesselbe.

    Hotte

    1. hi,

      Findet irgendjemand da irgendwie eine Lücke? Bin echt ratlos...

      Eine hätte ich: Deine Session-ID ist auch nach shift-reload immer noch diesselbe.

      Hotte

      Wie korrigiere ich das?

      --
      Mit freundlichen Grüßen
      seVes

      1. hi,

        Findet irgendjemand da irgendwie eine Lücke? Bin echt ratlos...

        Eine hätte ich: Deine Session-ID ist auch nach shift-reload immer noch diesselbe.

        Hotte

        Wie korrigiere ich das?

        Guck mal, was Eddi geschrieben hat ;-)

        Hotti

  3. ulkig ;)

    }else{
            echo '
            <div id="infoheadline">
                Beim Verbinden mit der Datenbank ist ein Fehler aufgetreten.
            </div>
            <div id="infomessage">
                Bitte kontaktieren Sie schnellstmöglich den Webmaster!<br><br>Vielen Dank.
            </div>';
            include("./content/contact.php");
        }

    mfg Beat

    --
    ><o(((°>           ><o(((°>
       <°)))o><                     ><o(((°>o
    Der Valigator leibt diese Fische
    1. Servus!

      ulkig ;)

      }else{
              echo '
              <div id="infoheadline">
                  Beim Verbinden mit der Datenbank ist ein Fehler aufgetreten.
              </div>
              <div id="infomessage">
                  Bitte kontaktieren Sie schnellstmöglich den Webmaster!<br><br>Vielen Dank.
              </div>';
              include("./content/contact.php");
          }

      mfg Beat

      Hilft mir jetzt wie genau weiter?

      --
      Mit freundlichen Grüßen
      seVes

      1. }else{
                echo '
                <div id="infoheadline">
                    Beim Verbinden mit der Datenbank ist ein Fehler aufgetreten.
                </div>
                <div id="infomessage">
                    Bitte kontaktieren Sie schnellstmöglich den Webmaster!<br><br>Vielen Dank.
                </div>';
                include("./content/contact.php");
            }
        Hilft mir jetzt wie genau weiter?

        Eben gar nicht.
        Falls du ein Problem hast, das du mitgeteilt haben willst, dann schreibe die entsprechende Automation.

        mfg Beat

        --
        ><o(((°>           ><o(((°>
           <°)))o><                     ><o(((°>o
        Der Valigator leibt diese Fische
        1. Servus!

          }else{
                  echo '
                  <div id="infoheadline">
                      Beim Verbinden mit der Datenbank ist ein Fehler aufgetreten.
                  </div>
                  <div id="infomessage">
                      Bitte kontaktieren Sie schnellstmöglich den Webmaster!<br><br>Vielen Dank.
                  </div>';
                  include("./content/contact.php");
              }
          Hilft mir jetzt wie genau weiter?

          Eben gar nicht.
          Falls du ein Problem hast, das du mitgeteilt haben willst, dann schreibe die entsprechende Automation.

          mfg Beat

          Achso. Ja stimmt *g* ;-)

          --
          Mit freundlichen Grüßen
          seVes

  4. Hallo Seves,

    vermutlich wird hier...

      include("./content/news.php");  
    

    ...die Session initiiert. Sie wird aber nirgends abgefragt oder auf Gültigkeit geprüft. Das ist aus der Tatsache ersichtlich, dass ich bei meinen Einträgen in Dein GB kein Session Cookie übersandt habe.

      			<form action="./index.php?page=guestbook&amp;send=guestbook" method="post">  
    

    Im action-Attribut könntest Du die Session als GET-Variable ganz komfortabel mitübergeben. Serverseitig müsste dann geprüft werden, ob mit der Session schon mal Formulardaten übermittelt wurden.

      					<img src="./content/captcha.php" title="Sicherheitscode" alt="Sicherheitscode" height="40px" width="140px"><br>&nbsp;  
    

    Es ist ja schön, dass Du hier ein Bild erstellen lässt. Nur beider Validierung der übergebenen Forumlareinträge ziehst Du diesen abgebildeten Wert nicht heran. Dieser sollte aber in der Session gespeichert sein. Nur, wie ja oben schon erwähnt, kümmert sich das Script nicht um die Session. So muss man lediglich einen sechs Zeichen langen String eingeben, schon ist Dein GB-script zufrieden und Du hast Spam.

    Gruß aus Berlin!
    eddi, Tester in Deinem GB

    1. Servus!

      Hallo Seves,

      vermutlich wird hier...

        include("./content/news.php");  
      

      ...die Session initiiert. Sie wird aber nirgends abgefragt oder auf Gültigkeit geprüft. Das ist aus der Tatsache ersichtlich, dass ich bei meinen Einträgen in Dein GB kein Session Cookie übersandt habe.

      Sie wird in index.php generiert und wird in send.php doch überprüft?

      if(isset($_SESSION['captcha_spam']) && (trim($security)!="") && (trim($security)!=$_SESSION['captcha_spam'])){  
                              $missing.="Der eingegebene Sicherheitscode ist nicht korrekt!<br>Bitte geben Sie den unten stehenden Sicherheitscode ein.";  
                      }
      
        			<form action="./index.php?page=guestbook&amp;send=guestbook" method="post">  
      

      Im action-Attribut könntest Du die Session als GET-Variable ganz komfortabel mitübergeben. Serverseitig müsste dann geprüft werden, ob mit der Session schon mal Formulardaten übermittelt wurden.

      Wäre eine weitere Möglichkeit.

        					<img src="./content/captcha.php" title="Sicherheitscode" alt="Sicherheitscode" height="40px" width="140px"><br>&nbsp;  
      

      Es ist ja schön, dass Du hier ein Bild erstellen lässt. Nur beider Validierung der übergebenen Forumlareinträge ziehst Du diesen abgebildeten Wert nicht heran. Dieser sollte aber in der Session gespeichert sein. Nur, wie ja oben schon erwähnt, kümmert sich das Script nicht um die Session. So muss man lediglich einen sechs Zeichen langen String eingeben, schon ist Dein GB-script zufrieden und Du hast Spam.

      Siehe oben. Es wird doch geprüft? Ist das Captcha falsch, kommt ein Fehler, da $missing gesetzt wurde und somit das INSERT unterdrückt.

      Und der Wert wird doch in der Session gespeichert?

      Gruß aus Berlin!
      eddi, Tester in Deinem GB

      --
      Mit freundlichen Grüßen
      seVes

      1. Hi,

        Das ist aus der Tatsache ersichtlich, dass ich bei meinen Einträgen in Dein GB kein Session Cookie übersandt habe.

        Lass' dir das auf der Zunge zergehen - was macht dein Script in diesem Fall?

        if(isset($_SESSION['captcha_spam']) && (trim($security)!="") && (trim($security)!=$_SESSION['captcha_spam'])){

        $missing.="Der eingegebene Sicherheitscode ist nicht korrekt!<br>Bitte geben Sie den unten stehenden Sicherheitscode ein.";
                        }

          
        Und wie wirkt sich obiges auf diesen Scriptabschnitt aus?  
          
        MfG ChrisB  
          
        
        -- 
        Light travels faster than sound - that's why most people appear bright until you hear them speak.