Login

Alternative to Captchas (Without Human Interaction)

Author:
Archatas
Posted:
September 28, 2008
Language:
Python
Version:
1.0
Tags:
captcha security form field antispam antibot
Score:
4 (after 4 ratings)

This security field is based on the perception that spambots post data to forms in very short or very long regular intervals of time, where it takes reasonable time to fill in a form and to submit it for human beings.

Instead of captcha images or Ajax-based security interaction, the SecurityField checks the time of rendering the form, and the time when it was submitted. If the interval is within the specific range (for example, from 5 seconds till 1 hour), then the submitter is considered as a human being. Otherwise the form doesn't validate.

Usage example:

class TestForm(forms.Form):
    prevent_spam = SecurityField()
    # ... other fields ...

The concept works only for unbounded forms.

 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
# -*- coding: UTF-8 -*-

import time
import datetime
import base64

from django import forms
from django.utils.translation import ugettext
from django.conf import settings

MIN_TIME = getattr(settings, "MIN_TIME", 5) # 5 seconds
MAX_TIME = getattr(settings, "MAX_TIME", 3600) # 1 hour

def cryptString(plain):
    # Your implementation for encrypting a string.
    # For example:
    return base64.encodestring(plain)    

def decryptString(cipher):
    # Your implementation for decrypting a string
    # For example:
    return base64.decodestring(cipher)

class SecurityField(forms.CharField):
    """
    A field which checks whether the form was filled in within the 
    given range of time
    
    The concept works only for Unbounded forms.
    """
    time_elapsed = 0
    
    def generate_value(self):
        started = cryptString(str(int(time.mktime(datetime.datetime.now().timetuple()))))
        return started
    def _pass_test(self, value):
        started = int(decryptString(value))
        current = int(time.mktime(datetime.datetime.now().timetuple()))
        self.time_elapsed = current - started
        return self.MIN_TIME < current - started < self.MAX_TIME
    def __init__(self, *args, **kwargs):
        super(type(self), self).__init__(*args, **kwargs)
        self.widget = forms.HiddenInput()
        self.initial = self.generate_value()
        self.required = True
        self.MIN_TIME = MIN_TIME
        self.MAX_TIME = MAX_TIME
    def clean(self, value):
        value = super(type(self), self).clean(value)
        if not self._pass_test(value):
            raise forms.ValidationError(ugettext(u"The data transfer didn't pass the security test. You are considered as a spambot."))
        return value

More like this

  1. Mathematical Captcha by dogada 7 years, 3 months ago
  2. Captcha without Freetype or the Python Imaging Library (PIL) by gregb 5 years, 10 months ago
  3. Display values from a bound (submitted) form by masida 1 year ago
  4. Multiple-Submit-Button Widget for Choice Field by Archatas 6 years, 7 months ago
  5. FieldAccessForm (per-field user access for forms derived from models) by Killarny 6 years, 5 months ago

Comments

Please login first before commenting.