+ Antworten
Ergebnis 1 bis 7 von 7

Thema: Simple CAPTCHA ohne GD - Sicher

  1. #1
    TP-Member nerdlikeyou macht alles soweit korrekt Avatar von nerdlikeyou
    Registriert seit
    Jun 2009
    Ort
    Augsburg
    Beiträge
    52

    Simple CAPTCHA ohne GD - Sicher

    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_queryMYSQL_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($cresult1MYSQL_ASSOC);
    $bild2 mysql_fetch_array($cresult2MYSQL_ASSOC);     
    $bild3 mysql_fetch_array($cresult3MYSQL_ASSOC);     
    $bild4 mysql_fetch_array($cresult4MYSQL_ASSOC);     
    $bild5 mysql_fetch_array($cresult5MYSQL_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($pqueryMYSQL_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>");
    $nachrichtnl2br(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($ausgabeergMYSQL_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
    Geändert von nerdlikeyou (22.06.2009 um 18:54 Uhr)

  2. #2
    TP-Moderator Adromir lebt für das TP und seine User Adromir lebt für das TP und seine User Adromir lebt für das TP und seine User Adromir lebt für das TP und seine User Adromir lebt für das TP und seine User Adromir lebt für das TP und seine User Adromir lebt für das TP und seine User Adromir lebt für das TP und seine User Avatar von Adromir
    Registriert seit
    Jun 2004
    Ort
    Hannover
    Beiträge
    4.805
    Sei mir nicht böse, aber Meiner Meinung nach ziemlich Imperformant und unnötig aufgebläht.

    Da würde ich dann z.B. eine Sicherheitsfrage (wieviel ist 1+1) zudem vorziehen. Captchas mit GD-Lib haben einfach mehr Möglichkeiten (zufällige Buchstabenfarbe, Größe, Schriftart, Drehung, Hintergrundvariationen) und sind mMn. vorzuziehen.
    Je größer der Deppenfaktor, desto gigantischer das Bescheidwissergefühl
    -Dieter Nuhr

  3. #3
    TP-Junior regis_hastur macht alles soweit korrekt
    Registriert seit
    Dec 2006
    Beiträge
    6
    Warum das Rad neu erfinden? Schau doch mal auf http://recaptcha.net/ vorbei ;-)

  4. #4
    TP-Junior http.refresh macht alles soweit korrekt
    Registriert seit
    Feb 2007
    Beiträge
    19
    1. Wuerde an deiner Stelle ein fertiges GD captcha nehmen.

    2.
    Code:
    $pcount = mysql_query("SELECT * FROM c_pruefung WHERE ip='$ipadresse'");
    Auch IP-Adressen validieren, laesst sich auch SQL code Einschleusen, sogar mit bissle php, perl kenntnissen ein einfaches exploit schreiben

    3. mysql real escape string > all wenns um sql injections vereiteln geht, um htmlspecialchars kommt man rum.

    just my 2 cents

    mfg

  5. #5
    TP-Member nerdlikeyou macht alles soweit korrekt Avatar von nerdlikeyou
    Registriert seit
    Jun 2009
    Ort
    Augsburg
    Beiträge
    52
    Ok, thx a lot.
    -> Hab ein fertiges CAPTCHA genommen und eingebunden... dat Ding war auch eher ne "Übung" um meine "ich code selber"-Fähigkeiten zu verbessern, weil immer nur Scripts "klauen" und einbetten is zwar nett aber wenn man dann modifizieren muss kommt man halt nicht drum rum das zeug auch zu verstehen...

    Hat jemand noch Tipps zum Thema "elegant" coden?
    Order irgendwelche Tipps? Ich bin grad am rumtun wegen datenbank-abfragen mir da eine funktion zu schreiben.

    so im stil

    PHP-Code:
    function dbabrage ($output$myquery) {
    $query $myquery;
    while (
    $output mysql_fetch_array($queryMYSQL_ASSOC))
    {return 
    "..."
    ;}
    ;} 
    und ab dem "..." gehts los. Wie mach ich die Augabe variabel ohne 1000x die Funktion zu modifizieren, sondern da nur die entsprechenden werte... also sowas wie $output['name']

    bei mir returnt der irgendwie nicht das ganze array *hmpf*
    Geändert von nerdlikeyou (02.07.2009 um 17:43 Uhr)

  6. #6
    TP-Moderator Adromir lebt für das TP und seine User Adromir lebt für das TP und seine User Adromir lebt für das TP und seine User Adromir lebt für das TP und seine User Adromir lebt für das TP und seine User Adromir lebt für das TP und seine User Adromir lebt für das TP und seine User Adromir lebt für das TP und seine User Avatar von Adromir
    Registriert seit
    Jun 2004
    Ort
    Hannover
    Beiträge
    4.805
    Also, ich würde den MySQL- Anteil komplett weglassen, die Bildernamen in ein Array packen

    PHP-Code:
    $images = array(
    'A'=>'blablub.jpg',
    'a'=>'mumpf.jpg',
    '1'=>'jipie.jpg'
    [...]
    ); 
    Dann den Captcha- String generieren und in eine Session laden

    mit
    PHP-Code:
    echo '<table>
              <tr>'
    ;
    foreach(
    $captcha_str AS $index) {
    echo 
    '<td><img src="/image_ordner/"'.$images["$index"].'</td>';
    }
    echo 
    '  </tr>
            </table>'

    gibst du dann die Bilder aus.

    Dann braucht man nur den abgesendeten String mit dem in der Session vergleichen.

    Zeitstempel und IP kannst du auch in die Session schreiben.
    Je größer der Deppenfaktor, desto gigantischer das Bescheidwissergefühl
    -Dieter Nuhr

  7. #7
    TP-Member nerdlikeyou macht alles soweit korrekt Avatar von nerdlikeyou
    Registriert seit
    Jun 2009
    Ort
    Augsburg
    Beiträge
    52
    Stimmt, das mit der SESSION is ja viel einfacher und bietet weniger Angriffsfläche von außen. Merci für die Anregung.

+ Antworten

Ähnliche Themen

  1. DB ABFRAGE und CAPTCHA
    Von dirkdirk im Forum TYPO3
    Antworten: 22
    Letzter Beitrag: 31.03.2009, 17:03
  2. CSS Simple Frage Simple Lösung????
    Von Comunio im Forum HTML & CSS
    Antworten: 9
    Letzter Beitrag: 26.11.2007, 14:48
  3. Captcha
    Von emiglio im Forum Traum-Dynamik
    Antworten: 10
    Letzter Beitrag: 19.07.2007, 18:18
  4. Captcha
    Von keyframe im Forum Low Budget
    Antworten: 0
    Letzter Beitrag: 28.09.2006, 19:12
  5. Antworten: 11
    Letzter Beitrag: 11.04.2005, 18:25

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

     

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