Login

Alternative to Captchas (Without Human Interaction)

Author:
Archatas
Posted:
September 28, 2008
Language:
Python
Version:
1.0
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. Template tag - list punctuation for a list of items by shapiromatron 3 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 3 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 10 months, 2 weeks ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 11 months, 1 week ago
  5. Help text hyperlinks by sa2812 12 months ago

Comments

Please login first before commenting.