Spam vanaf contactformulier(en) blokkeren

Status
Niet open voor verdere reacties.

hfoppen

Terugkerende gebruiker
Lid geworden
15 nov 2000
Berichten
1.056
Hoi,

ik heb een contactformulier (zie onderstaand), en vandaar worden vaak spamberichten verstuurd (via zo'n bot). Vaak zijn dit berichten met links etc. erin. Heb dit ook vaak bij gastenboeken.

Ik weet dat je zo'n capcha kunt gebruiken, maar krijg ik niet echt voor elkaar. Je moet ook iets kunnen doen, dat je geen HTML-code accepteert in een bericht ofzo. Wie o wie kan onderstaande voor mij wijzigen dat het vermindert? Alvast bedankt..

contact.php:
PHP:
		<table><form action="resultaat.php" method="post"><input type="hidden" value="1" name="send"> 
    	  	<tr>
				<td><span class="style1">Uw naam:</span></td>
				<td><input name="naam" type="text" class="style1" size="20"></td>
			</tr> 
    		<tr> 
				<td><span class="style1">Uw mail adres:</span></td>
				<td><input name="email" type="text" class="style1" size="20"></td>
			</tr> 
		    <tr>
				<td valign="top"><span class="style1">Uw bericht:</span></td>
				<td><textarea name="bericht" cols="60" rows="10" class="style1"></textarea></td>
			</tr> 
		    <tr>
				<td></td>
				<td>
					<input name="submit" type="submit" value="Verzenden">
				    <input type="reset" name="Reset" value="Annuleren">
				</td> 
			</tr> 
        </form> 
		</table>

En de resultaat.php:
PHP:
	<?php  
	  //stukje code om ingevoerde velden te lezen, controleren en te verzenden
if($submit){    
    if(strlen($naam)==0){    
        $error_msg[] = "U moet een geldige naam opgeven!<br>";    
    }    
    if((strlen($naam)!=0) && (strlen($naam) < 3)){    
        $error_msg[] .= "U naam moet minimaal uit 3 tekens bestaan!<br>";    
    }    
     if(strlen($email)==0){    
        $error_msg[] .= "Vul alstublief een geldig e-mail adres in!<br>";    
    }    
if((strlen($email)!=0) && (!ereg("^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@([a-zA-Z0-9-]+\.)+([a-zA-Z]{2,4})$", $email))){ // email moet geldige constructie hebben, bv ali.g@test.nl 
        $error_msg[] .= "E-mail adres is ongeldig, vul dit correct in!<br>";    
    }    
    if(strlen($bericht)==0){    
        $error_msg[] .= "Vul een bericht in!<br>";    
    }    
    if((strlen($bericht)!=0) && (strlen($bericht) < 5)){    
        $error_msg[] .= "Het bericht moet minimaal uit 5 tekens bestaan!<br>";    
    }    
    if($error_msg){ // als dingen niet correct zijn ingevult 
        echo "<font face=verdana size=1>";    
        echo "Uw bericht kon niet verzonden worden vanwege de volgende redenen: <br><br>";    
        for($i = 0, $j = 1; $i < 4; $i++, $j++){    
            if($error_msg[$i]){    
                echo $j . ". " . $error_msg[$i];    
            }    
        }    
        echo "<br>Ga <a href=javascript:history.go(-1)>terug</a> om het probleem te verhelpen.";    
        echo "</font>";    
        }else{
		 
		$mail = "info@domein.nl"; 
		
        $onderwerp = "Reactie vanaf domein.nl";    
        $header = "From: " . $email . "\n";    
        $body = "Datum van verzending: " . date("d-m-Y") . " om " . date("H:i:s") . ".\n";    
        $body .= "De volgende informatie werd verzonden:\n\n";    
        $body .= "Naam: " . $naam . "\n";    
        $body .= "E-mailaddress: " . $email . "\n\n";    
        $body .= "Vraag:\n";    
        $body .= $bericht ;   
		
		$Naam="Naam					: $naam\n"; 
		$Email="E-mail				: $email\n"; 
        mail($mail, $onderwerp, $body, $header);	
		

        // Formulier uitgevoerd, mensen bedanken 
        echo "Bedankt voor uw reactie. ";  
		?>
		<meta http-equiv="refresh" content="3;URL=index.php">  
		<?
}}
//einde van pagina!!
?>
 
ten eerste: oudere post: hier (ook over captcha's)

hier een simpel zelfgemaakt captcha script:
PHP:
<?php
header("Content-type: image/png"); 
$text = stripslashes($_GET['text']);
$bc = stripslashes($_GET['bc']);
$fc = stripslashes($_GET['fc']);
$number = (strlen($text))*7+9;   
$im = imagecreate($number, 24); 
$colour1 = imagecolorallocate($im, $bcr, $bcg, $bcb); 
$colour2 = imagecolorallocate($im, $fcr, $fcg, $fcb); 
imagestring($im, 3, 5, 5,  $text, $colour2);
imagepng($im);
imagedestroy($im);
?>

roep je aan (op je pagina) met:
PHP:
url_naar_bestand/imagetext.php?text=Text&bcr=0&bcg=0&bcb=0&fcr=250&fcg=0&fcb=250
 
Ik kon zo gauw niets anders bedenken maar onderstaande code controleert of er HTML in de variabele staat.

PHP:
// Created by Tha Devil
// Helpmij.nl forum
if(strlen($_POST['bericht']) == strlen(strip_tags($_POST['bericht']))) {
  echo 'Dit bericht bevat geen HTML';
}
else {
  echo 'HTML detected!!';
}
NIET GETEST!

Het controleert gewoon of de lengte van het bericht gelijk blijft wanneer je strip_tags(); toepast.
Zoals je wellicht begrijpt haalt strip_tags alle HTML en PHP code uit een string.
 
Code in het contactformulier (contact.php)
Code:
<tr>
  <td><img <?php if(isset($scode)){ echo $scode; } ?>src="code.php?<?php echo substr(md5(time()),6); ?>" /></td>
  <td><input <?php if(isset($stylecode)){ echo $stylecode; } ?> name="fcode" type="text" /></td>
</tr>

Controle in resultaatpagina (resultaat.php)
PHP:
if($_GET['fcode'] != $_GET['scode']) {
	$error_msg[] .= "Code komt niet overeen!<br>.";
}

De controle gaat niet goed. Wat doe ik fout? Zal wel iets met die $_GET etc. zijn!?
 
Beste HFoppen,

Spam is een naar ding, maar spam is vooral dom. Captcha werkt heel prettig voor de programmeur, maar is wat onvriendelijk voor de gebruiker. (het komt niet vaak, maar wel te vaak voor dat mensen het niet kunnen lezen).

Er is veel onderzoek gedaan naar hoe je spambots tegen kunt houden. Vaak werkt een combinatie van 2 methodes, de bot valt altijd wel voor een van de methodes.

Methode 1: Hou hem maar voor de gek
Bots worden gedreven door het veld email. Dat is het veld waarmee zij de persoon die ze zoeken bereiken, dus dat veld zullen ze altijd invullen. Op de volgende manier hou je hem prima voor de gek:
HTML:
<label for="email" style="position:absolute;left:-9999px;">Dit is een antispam veld. Laat deze leeg <input type="text" name="email" id="email" value="" style="position:absolute;left:-9999px;" /></label>
<label for="appelschil">E-mail <input type="text" name="appelschil" id="appelschil" value="" /></label>

Je spambot zal het veld nu wel zien, maar de gebruiker niet. De computer vult altijd het e-mail adres in. Dus check bij de submit of het is ingevuld en zoja dan toon je het formulier lief de deur:

PHP:
    if($_REQUEST["email"]!=""){    
        $error_msg[] = "U heeft het anti spam veld ingevuld! Laat dit veld leeg...<br>";    
    }

Methode twee
De spam bot wil zo snel mogelijk zo veel mogelijk resultaten. Hij zal dus met maximale snelheid invullen, en dat is sneller dan dat jij het ooit met je hand zal kunnen. Dus controleer maar lekker hoelang de gebruiker er over gedaan heeft om het veld in te vullen.

PHP:
echo "<input type=\"hidden\" name=\"sneeuwwitje\" id=\"sneeuwwitje\" value=\"" . ((isset($_REQUEST["sneeuwwitje"])) ? $_REQUEST["sneeuwwitje"] : time())  . "\" />";

Note: als het formulier al een waarde heeft voor $_REQUEST dan laat je die staan. (het isset() stukje). Op het moment dat iemand te zien krijgt "je hebt dat niet ingevuld" dan kan hij het formulier namelijk veel sneller invullen. Dus blijf maar kijken naar de begin tijd.

Als het formulier binnenkomt dan kijk je of het langer dan 10 seconde en korter dan een uur duurde om het formulier in te vullen:
PHP:
    $timetaken = time() - $_REQUEST["sneeuwwitje"];
    if($timetaken>time()-10){
        $error_msg[] = "U heeft het formulier te snel ingevuld.<br>";    
    }

   if($timetaken<time()-(60*60)){
        $error_msg[] = "U heeft het formulier niet snel genoeg ingevuld.<br>";   
  }


Zoals je ziet gebruik ik namen als sneeuwwitje en appelschil. Je bot snapt niks van die namen, en dat willen we ook graag zo houden.

Wout
 
Laatst bewerkt:
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan