WebBot Abwehr:

Ich möchte hier ein paar Möglichkeiten zur Abwehr von Spam-Webbots vorstellen. Das Problem: WebBots scannen die Website und füllen ihre Spam-Werbung in alle Formulare, die sie finden können.

Die meisten Leute setzen Chaptchas gegen dieses Problem ein, jedoch ist das keine elegante Lösung. Erstens ist es für den Benutzer ziemlich aufwendig die Zahlen von einem Bild zu lesen und abzutippen. Zweitens ist es keineswegs barrierefrei. Sehbehinderte Menschen haben hier oft Probleme. Drittens gibt es schon Projekte, die sich mit der Texterkennung von Captchas beschäftigen. Siehe hier: http://caca.zoy.org/wiki/PWNtcha

Ich schlage hierfür eine andere Vorgehensweise vor: WebBots verhalten sich oft recht auffällig. Sie füllen Pflichtfelder richtig aus, scannen das Formular und posten es innerhalb weniger Sekunden, sie verwenden immer bestimmte Werbelinks. Dieses auffällige Verhalten lässt sich bestimmen. Haben wir einen Verdachtsfall, so leiten wir erst dann auf ein Captcha um.

Abwehrmöglichkeiten:

Pflichtfelder

Wir bauen in unser Formular bestimmte Felder ein, die gefüllt werden müssen. Beispiel: ein Emailfeld mit einer gültigen Emailadresse.

Leider erkennen fast alle Webbots so ein Emailfeld und füllen dieses mit einer gültigen Emailadresse.

Dieses Verhalten lässt sich aber für unsere Zwecke nutzen. Wir bauen ein Emailfeld ein, das wir per CSS ausblenden. Und wenn wir das Formular auswerten, darf das Feld nicht gefüllt sein.

field.html
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
<style type="text/css"> tr#someID { visibility: collapse; display: none; } </style>
<form method="POST" name="comment" action="submit.php">
<table>
	<tr>
		<td align="right"><b>Name</b></td>
		<td><input type="text" name="name" size="30"></td>
	</tr>
	<tr id="someID">
		<td align="right"><b>E-mail:</b></td>
		<td><input type="text" name="email" size="30"></td>
	</tr>
	<tr>
		<td align="right"><b>E-mail:</b></td>
		<td><input type="text" name="mail" size="30"></td>
	</tr>
	<tr>
		<td align="right" valign="top"><b>Kommentar</b></td>
		<td><textarea rows="10" name="message" cols="40"></textarea></td>
	</tr>
	<tr>
		<td>&nbsp;</td>
		<td width="500"><input type="submit" value="Eintragen" name="sub"></td>
	</tr>
</table>
</form>
submit.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php

    
if(isset($_POST['name']) && isset($_POST['mail']) && isset($_POST['message'])) {

        if(!empty(
$_POST['email'])) { //perhaps a bot
            
            
die();

        }

        
//insert data
        //$db->insert(array($_POST['name'], $_POST['mail'], $_POST['message']),'comment');
        
echo "Daten eingetragen: ".$_POST['name'].'|'.$_POST['mail'].'|'.$_POST['message'];
    }

?>

Zeit

Ein Bot wird nur einige Sekunden für so ein Formular brauchen. Ein Mensch wird mehr Zeit benötigen, um es auszufüllen.

field_time.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<form method="POST" name="comment" action="submit_time.php">
<input type="hidden" name="id" value="<?=time()?>">
<table>
	<tr>
		<td align="right"><b>Name</b></td>
		<td><input type="text" name="name" size="30"></td>
	</tr>
	<tr>
		<td align="right"><b>E-mail:</b></td>
		<td><input type="text" name="mail" size="30"></td>
	</tr>
	<tr>
		<td align="right" valign="top"><b>Kommentar</b></td>
		<td><textarea rows="10" name="message" cols="40"></textarea></td>
	</tr>
	<tr>
		<td>&nbsp;</td>
		<td width="500"><input type="submit" value="Eintragen" name="sub"></td>
	</tr>
</table>
</form>
submit_time.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
    
    
if(isset($_POST['name']) && isset($_POST['mail']) && isset($_POST['message'])) {

        if(!isset(
$_POST['id']) || !is_numeric($_POST['id']) || $_POST['id']+10 time()) { //perhaps a bot
            
            
die("You are very quick in filling in all fields");

        }

        
//insert data
        //$db->insert(array($_POST['name'], $_POST['mail'], $_POST['message']),'comment');
        
echo "Daten eingetragen: ".$_POST['name'].'|'.$_POST['mail'].'|'.$_POST['message'];
    }

?>

JavaScript

Viele Spambots führen auch JavaScript nicht aus.

field_javascript.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<form method="POST" name="comment" action="submit_javascript.php">
<input type="hidden" name="id" value="">
<table>
    <tr>
        <td align="right"><b>Name</b></td>
        <td><input type="text" name="name" size="30"></td>
    </tr>
    <tr>
        <td align="right"><b>E-mail:</b></td>
        <td><input type="text" name="mail" size="30"></td>
    </tr>
    <tr>
        <td align="right" valign="top"><b>Kommentar</b></td>
        <td><textarea rows="10" name="message" cols="40"></textarea></td>
    </tr>
    <tr>
        <td>&nbsp;</td>
        <td width="500"><input type="submit" value="Eintragen" name="sub"></td>
    </tr>
</table>
</form>
<script type="text/javascript">document.comment.id.value = 'mkz5erAskd569djwlj234n';</script>
submit_javascript.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
    
    
if(isset($_POST['name']) && isset($_POST['mail']) && isset($_POST['message'])) {

        if(
$_POST['id'] != 'mkz5erAskd569djwlj234n') { //perhaps a bot
            
            
die("JavaScript was not executed ");

        }

        
//insert data
        //$db->insert(array($_POST['name'], $_POST['mail'], $_POST['message']),'comment');
        
echo "Daten eingetragen: ".$_POST['name'].'|'.$_POST['mail'].'|'.$_POST['message'];
    }

?>

Text Analysieren

Der Text liefert auch oft einen Anhaltspunkt darüber, ob die Nachricht ein Spam ist. Oft wird versucht, einen Link zu posten. Auf diesen Inhalt lässt sich dann filtern.

field_content.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<form method="POST" name="comment" action="submit_content.php">
<table>
    <tr>
        <td align="right"><b>Name</b></td>
        <td><input type="text" name="name" size="30"></td>
    </tr>
    <tr>
        <td align="right"><b>E-mail:</b></td>
        <td><input type="text" name="mail" size="30"></td>
    </tr>
    <tr>
        <td align="right" valign="top"><b>Kommentar</b></td>
        <td><textarea rows="10" name="message" cols="40"></textarea></td>
    </tr>
    <tr>
        <td>&nbsp;</td>
        <td width="500"><input type="submit" value="Eintragen" name="sub"></td>
    </tr>
</table>
</form>
submit_content.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
    
    
if(isset($_POST['name']) && isset($_POST['mail']) && isset($_POST['message'])) {

        if( (
strpos($_POST['message'], '<a')!==false && strpos($_POST['message'], '</a>')!==false) || strpos($_POST['message'], '[url=')!==false) { //perhaps a bot
            
            
die("You try to Post Links");

        }

        
//insert data
        //$db->insert(array($_POST['name'], $_POST['mail'], $_POST['message']),'comment');
        
echo "Daten eingetragen: ".$_POST['name'].'|'.$_POST['mail'].'|'.$_POST['message'];
    }

?>

IPs blocken

Eine weitere effektive Methode ist bei jedem identifizierten Spam die IP mitzuloggen und die entsprechenden SPAM-IPs daraufhin zu blocken.

Ich empfehle auf jeden Fall, das nicht zu automatisieren. Denn dies könnte mit falschen IP-Paketen für einen Angriff ausgenützt werden.

Anmerkung: Außerdem ist überhaupt fraglich, ob es sinvoll ist, bestimmte IPs zu blocken. Eventuell kommen richtige IPs in die Spamliste und dann hat ein normaler Benutzer keinen Zugriff mehr auf Eure Seite. Dies kann durch gefälschte IP-Pakete passieren oder wenn die Spammer für ihre Attacken fremde Rechner hernehmen.

ipblock.php
1
2
3
4
5
6
7
<?php

$ipSpamBlockList 
= array('95.79.72.76''65.34.164.210''68.233.226.74''96.31.87.133''96.31.87.133''89.96.245.132''95.79.70.102''95.79.65.0''109.195.233.109''59.185.104.189''95.215.0.195');
if(
in_array($_SERVER["REMOTE_ADDR"], $ipSpamBlockList))
    die(
'Your IP is on the SPAM LIST');


Captcha

So, und nun fügen wir diese Methoden noch zusammen und kombinieren sie mit einem Captcha.

captcha.php
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
<?php
    session_start
();

    
$ipSpamBlockList = array('95.79.72.76''65.34.164.210''68.233.226.74''96.31.87.133''96.31.87.133''89.96.245.132''95.79.70.102''95.79.65.0''109.195.233.109''59.185.104.189''95.215.0.195');

    
$limit 2

    
$spam=0;
        
    if(isset(
$_POST['name']) && isset($_POST['mail']) && isset($_POST['message'])) {

        if(!empty(
$_POST['email']))
            
$spam++;
        if(!isset(
$_POST['id']) || !is_numeric($_POST['id']) || $_POST['id']+10 time())
            
$spam++;
        if(
$_POST['id2'] != 'mkz5erAskd569djwlj234n')
            
$spam++;
        if((
strpos($_POST['message'], '<a')!==false && strpos($_POST['message'], '</a>')!==false) || strpos($_POST['message'], '[url=')!==false)
            
$spam++;
        if(
in_array($_SERVER["REMOTE_ADDR"], $ipSpamBlockList))
            
$spam++;

        if(
$spam $limit || (isset($_SESSION['captcha_code']) && $_SESSION['captcha_code']==$_POST['captcha'])) {
            
            
//insert data
            //$db->insert(array($_POST['name'], $_POST['mail'], $_POST['message']),'comment');
            
echo "Daten eingetragen: ".$_POST['name'].'|'.$_POST['mail'].'|'.$_POST['message'];
            unset(
$_SESSION['captcha_code']);
            exit();
        }
    }

    if(
$spam >= $limit) {
        
        
$_SESSION['captcha_code']='';
        
$chrs 'abcdefghijklmnopqrstuvwxyz123456789';
        for(
$i=0;$i<6;$i++)
            
$_SESSION['captcha_code'] .= $chrs[rand(0,35)];
    }
?>


<style type="text/css"> tr#someID { visibility: collapse; display: none; } </style>
<form method="POST" name="comment" action="captcha.php">
<input type="hidden" name="id" value="<?=time()?>">
<input type="hidden" name="id2" value="">
<table>
    <tr>
        <td align="right"><b>Name</b></td>
        <td><input type="text" name="name" size="30" value="<?=(isset($_POST['name'])?$_POST['name']:'')?>"></td>
    </tr>
    <tr id="someID">
        <td align="right"><b>E-mail:</b></td>
        <td><input type="text" name="email" size="30"></td>
    </tr>
    <tr>
        <td align="right"><b>E-mail:</b></td>
        <td><input type="text" name="mail" size="30" value="<?=(isset($_POST['mail'])?$_POST['mail']:'')?>"></td>
    </tr>
    <tr>
        <td align="right" valign="top"><b>Kommentar</b></td>
        <td><textarea rows="10" name="message" cols="40"><?=(isset($_POST['message'])?$_POST['message']:'')?></textarea></td>
    </tr>
<?    if(isset($_SESSION['captcha_code'])) { ?>
    <tr>
        <td><b>Captcha:</b></td>
        <td width="500"><img src="captcha_image.php"><br><input type="text" name="captcha"></td>
    </tr>
<?    ?>
    <tr>
        <td>&nbsp;</td>
        <td width="500"><input type="submit" value="Eintragen" name="sub"></td>
    </tr>
</table>
</form>
<script type="text/javascript">document.comment.id2.value = 'mkz5erAskd569djwlj234n';</script>