Vai a: [ Contenuti ] [ Categorie ] [ Cerca ]

Rivisitazione della tecnica honeypot per moduli antispam senza captcha - UPDATE

Rivisitazione della tecnica “honeypot” per moduli antispam senza captcha – UPDATE


Esempio n° 4

Gli esempi appena proposti non fermano i cosìdetti “Formfills bot”, ovvero quelli che ripetono una procedura registrata.
Anche dando un nome completamente random ai campi di testo (un codice al posto di “email”, “messaggio” etc etc) un tool come Selenium è in grado di individuare gli input da riempire basandosi sulla gerarchia degli elementi. Per risolvere anche questo inconveniente sfruttiamo l’evento “keypress”. Selenium, infatti, non permette l’intercettazione dei tasti sulla tastiera e quindi siamo in grado di distinguere tra un modulo riempito a mano ed uno in automatico.

Codice da inserire in testa alla pagina:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
/*
 * Filename:	antispam-form4.php
 */
session_start();
$salt 		= 'parola-segreta';
$rchar		= chr(97 + mt_rand(0, 25));
$time 		= time();
$hash_real 	= md5($salt.$time.$rchar);
$hash_fake 	= md5($salt.($time+rand(1,999)).$rchar);
$code_real	        = $rchar.$hash_real;
$code_fake	= $rchar.$hash_fake;
 
$_SESSION["hashcode"] = $hash_real; 
// oppure usiamo i cookie con: setcookie('hashcode',$hash_real, 0, '/'); 
?>

Utilizziamo jQuery nell’head della pagina:

1
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

Aggiungiamo, al codice già visto, 2 nuovi funzioni:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script type="text/javascript">
<!--
$(document).ready(function() {
 
	$('#<?php echo $code_real; ?>').attr("autocomplete","off");
	$('.<?php echo $code_real; ?>').css('display','none');
	$('#formtime').append('<input type="hidden" id="rchar" name="rchar" value="<?php echo $rchar; ?>" />');
 
        $('#subject').bind('copy paste', function(e) {
		e.preventDefault();
	});
 
	$('#subject').keypress(function() {
		if ($('#<?php echo $rchar; ?>_control').length == 0) {
			$('#subject').append('<input type="hidden" id="<?php echo $rchar; ?>_control" name="<?php echo $rchar; ?>_control" />');
 			$('#<?php echo $rchar; ?>_control').val('<?php echo $code_real; ?>');
		}
	});
});
//-->
</script>

Vediamo cosa fanno nel dettaglio le 2 funzioni:

1
2
3
4
5
6
7
8
9
10
        $('#subject').bind('copy paste', function(e) {
		e.preventDefault();
	});
 
	$('#subject').keypress(function() {
		if ($('#<?php echo $rchar; ?>_control').length == 0) {
			$('#subject').append('<input type="hidden" id="<?php echo $rchar; ?>_control" name="<?php echo $rchar; ?>_control" />');
 			$('#<?php echo $rchar; ?>_control').val('<?php echo $code_real; ?>');
		}
	});

Sono agganciate al campo “subject” ma possiamo scegliere il campo che preferiamo (ottimo il campo “email” se presente).
Prima di tutto impediamo il “copia/incolla” su quel campo perchè, se venisse usata la funzione “incolla” con il tasto destro del mouse, non verrebbe intercettato l’evento “keypress”.

Il modulo html, invece, non subisce cambiamenti rispetto agli esempi precedenti.

Una volta intercettato l’evento “keypress” (valido anche su tastiere virtuali di smartphone e tablet) viene inserito un campo che ha, come nome, il carattere di controllo più un suffisso e, come valore, il codice hash generato in precedenza.

L’ulteriore controllo, infatti, si basa proprio sul fatto che i tool automatici non scatenano l’evento keypress e questo ci permette di inserire un ulteriore “checkpoint” sulla presenza o meno del campo “control”.

Vediamo la pagina di invio:

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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<?php
/*
 * Filename: result4.php
 */
session_start();
 
$salt 		= 'parola-segreta';
$minsec		= 1;
$now 		= time();
 
// il metodo di invio è post
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
 
	// esiste il campo con il carattere random e non è vuoto
	if (!empty($_POST['rchar'])) {
 
		// esiste il campo con la data e non è vuoto
		if (!empty($_POST['formtime'])) {
 
			//  il campo con la data è numerico
			if (is_numeric($_POST['formtime'])) {
 
				// la data di invio è futura rispetto a quella del form
				if ($now > $_POST['formtime']) {
 
					// il tempo trascorso tra il caricamento e l'invio è maggiore di n secondi
					if (($now - $_POST['formtime']) > $minsec) {
 
						// esiste la sessione
						if (isset($_SESSION['hashcode'])) {
 
							// se il contenuto della sessione è uguale alla chiave generata con il salt
							if ($_SESSION['hashcode'] == md5($salt.$_POST['formtime'].$_POST['rchar'])) {
 
								// ho i dati per comporre il nome del campo honeypot
								$honeypot = $_POST['rchar'].$_SESSION['hashcode'];
								// ho i dati per comporre il campo control
								$idcontrol = $_POST['rchar']."_control";
 
								// controllo l'esattezza del campo control
								if (!empty($_POST[$idcontrol]) && $_POST[$idcontrol] == $honeypot) {
 
									// il campo fake esiste ed è vuoto
									if (isset($_POST[$honeypot]) && empty($_POST[$honeypot])) {
 
										$result = "messaggio scritto da umani: $_POST[$idcontrol]";
 
									} else {
 
										$result = "bot: riempito campo fake o mancante";
									}
 
								} else {
 
									$result = "bot: non esiste il campo control";
								}
 
							} else {
 
								echo "codice sessione: " .$_SESSION['hashcode'];
								echo "<br />";
								echo "codice generato: " .md5($salt.$_POST['formtime'].$_POST['rchar']);
								echo "<br /><br />";
								$result = "bot: il contenuto della sessione non corrisponde al codice generato";
							}
 
						} else {
 
							$result = "bot: non esiste la sessione";
						}
 
					} else {
 
						$result = "bot: troppo veloce - tempo di invio: " .($now - $_POST['formtime']). " secondi";
					}
 
				} else {
 
					$result = "bot: troppo veloce - tempo di invio: futuro";
				}
 
			} else {
 
				$result = "bot: time manomesso";
			}
 
		} else {
 
			$result = "bot: manca timestamp";
		}
 
	} else {
 
		$result = "bot: manca il campo rchar";
	}
 
} else {
 
	$result = "bot: la request è diversa da POST";
}
 
/**************** INVIO EMAIL ******************/
$dest	 = "miaemail@provider.com";
$headers 	 = "X-Mailer: PHP ".phpversion()."\n";
$headers 	.= "From: $_POST[email] <$_POST[email]>\n";
$headers 	.= "Return-Path: $dest <$dest>\n";
$headers 	.= "Reply-To: $dest <$dest>\n";
$headers 	.= "Date: ".date("H:i:s")." ".date("d/m/Y")."\n";
$headers 	.= "Delivered-to: $dest <$dest>\n";
$headers	.= "MIME-Version: 1.0\n";
$corpo	 = "ora invio: " .$now. "\n ora form: " .$_POST['formtime']. "\r\n" .stripslashes($_POST["message"]);
if (isset($honeypot) && !empty($_POST[$honeypot])) {
$corpo	.= "\r\n honeypot:" .stripslashes($_POST[$honeypot]);
}
 
//invio dell'email
mail($dest,$result,$corpo,$headers);
 
setcookie('hashcode','', -1000, '/');
 
echo $result;
 
?>

Ricostruiamo il nome del campo “control” mettendo insieme il carattere random e il suffisso “_control”. Una volta fatto questo siamo in grado di confrontare il valore del campo con il nostro codice hash. Se tutto coincide il form è valido e possiamo andare avanti con la validazione.

1
2
3
4
5
6
7
8
// ho i dati per comporre il campo control
$idcontrol = $_POST['rchar']."_control";
 
	// controllo l'esattezza del campo control
	if (!empty($_POST[$idcontrol]) && $_POST[$idcontrol] == $honeypot) {
 
		// vado avandi con la validazione
	}

Download esempi

Per scaricare gli esempi potete cliccare su antispam-form.zip.

Attendo eventuali commenti da chi ha deciso di provare.

Pagina: 1 2 3 4 5 6 7 [8]

link sponsorizzati

Consiglialo su Facebook

Scrivi un commento

Commenti totali: 2


  1. bell’articolo! complimenti!!!

  2. l’ho provato e funziona bene come tecnica

Lascia un Commento

Iscriviti alle discussione senza commentare

Torna: [ Inizio ] [ Contenuti ] [ Categorie ] [ Cerca ]

Pagina renderizzata in soli 0,470 secondi dopo aver eseguito ben 52 query. Wordpress... prestazioni da urlo!