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 | from django import forms
from django.conf import settings
try:
from hashlib import md5
except ImportError:
from md5 import md5
class SecureForm(forms.Form):
"""
>>> from django import forms
>>> from forms_test.secure_forms import SecureForm
>>>
>>> class TF(SecureForm):
... name = forms.CharField(max_length=10)
... age = forms.IntegerField(widget=forms.HiddenInput())
... email = forms.EmailField(widget=forms.HiddenInput(), required=False)
...
>>>
>>> t = TF(initial={'age':20})
>>> p = TF({'name':'theju','age': 30, 'form_hash': t.initial['form_hash']})
>>> p.is_valid()
False
>>> p.errors
{'__all__': [u'Form has been tampered!']}
>>> p = TF({'name':'theju','age': 20, 'form_hash': t.initial['form_hash'], 'email': 'test@example.com'})
>>> p.is_valid()
False
>>> p.errors
{'__all__': [u'Form has been tampered!']}
>>> t = TF(initial={'age': 20, 'email': 'test@example.com'})
>>> p = TF({'name':'theju','age': 20, 'form_hash': t.initial['form_hash'], 'email': 'test@example.com'})
>>> p.is_valid()
True
>>> p = TF({'name':'theju','age': 20, 'form_hash': 'nonsense', 'email': 'test@example.com'})
>>> p.is_valid()
False
>>> p.errors
{'__all__': [u'Form has been tampered!']}
>>>
>>> class TestForm(SecureForm):
... name = forms.CharField(max_length=10)
... age = forms.IntegerField()
...
>>> t = TestForm({'name':'theju','age':50})
>>> t.is_valid()
True
>>> t.errors
{}
"""
def __init__(self, *args, **kwargs):
super(SecureForm, self).__init__(*args, **kwargs)
form_hash = forms.CharField(widget=forms.HiddenInput(),required=False)
self.fields.update({'form_hash': form_hash})
hash_str = ""
for name, field in self.fields.items():
if name != 'form_hash' and field.widget.is_hidden and self.initial.get(name, None):
hash_str += unicode(self.initial[name])
if hash_str:
hash_val = md5(hash_str+settings.SECRET_KEY).hexdigest()
self.initial['form_hash'] = hash_val
def clean(self):
hash_str = ""
for name, field in self.fields.items():
if name != 'form_hash' and field.widget.is_hidden and self.cleaned_data.get(name, None):
hash_str += unicode(self.cleaned_data[name])
if hash_str:
hash_val = md5(hash_str+settings.SECRET_KEY).hexdigest()
if hash_val and hash_val != self.cleaned_data['form_hash']:
raise forms.ValidationError("Form has been tampered!")
return self.cleaned_data
|
Comments