negative_captcha 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +61 -44
- data/lib/negative_captcha/form_builder.rb +30 -2
- data/lib/negative_captcha/view_helpers.rb +21 -0
- metadata +2 -2
data/README.markdown
CHANGED
@@ -12,13 +12,17 @@ In a negative captcha form there are two main parts and three ancillary parts. I
|
|
12
12
|
|
13
13
|
Honeypots are form fields which look exactly like real form fields. Bots will see them and fill them out. Humans cannot see them and thusly will not fill them out. They are hidden indirectly- usually by positioning them off to the left of the browser. They look kind of like this:
|
14
14
|
|
15
|
-
|
15
|
+
```html
|
16
|
+
<div style="position: absolute; left: -2000px;"><input type="text" name="name" value="" /></div>
|
17
|
+
```
|
16
18
|
|
17
19
|
### Real fields
|
18
20
|
|
19
21
|
These fields are the ones humans will see, will subsequently fill out, and that you'll pull your real form data out of. The form name will be hashed so that bots will not know what it is. They look kind of like this:
|
20
22
|
|
21
|
-
|
23
|
+
```html
|
24
|
+
<input type="text" name="685966bd3a1975667b4777cc56188c7e" />
|
25
|
+
```
|
22
26
|
|
23
27
|
### Timestamp
|
24
28
|
|
@@ -38,7 +42,9 @@ This is simply some key that is used in the hashing method to prevent bots from
|
|
38
42
|
|
39
43
|
You can let bundler install Negative Captcha by adding this line to your application’s Gemfile:
|
40
44
|
|
41
|
-
|
45
|
+
```ruby
|
46
|
+
gem 'negative_captcha'
|
47
|
+
```
|
42
48
|
|
43
49
|
And then execute:
|
44
50
|
|
@@ -48,37 +54,46 @@ And then execute:
|
|
48
54
|
|
49
55
|
Place this before filter at the top of the controller you are protecting:
|
50
56
|
|
51
|
-
|
57
|
+
```ruby
|
58
|
+
before_filter :setup_negative_captcha, :only => [:new, :create]
|
59
|
+
```
|
52
60
|
|
53
61
|
In the same controller include the following private method:
|
54
62
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
63
|
+
```ruby
|
64
|
+
private
|
65
|
+
def setup_negative_captcha
|
66
|
+
@captcha = NegativeCaptcha.new(
|
67
|
+
:secret => NEGATIVE_CAPTCHA_SECRET, #A secret key entered in environment.rb. 'rake secret' will give you a good one.
|
68
|
+
:spinner => request.remote_ip,
|
69
|
+
:fields => [:name, :email, :body], #Whatever fields are in your form
|
70
|
+
:params => params
|
71
|
+
)
|
72
|
+
end
|
73
|
+
```
|
64
74
|
|
65
75
|
Modify your POST action(s) to check for the validity of the negative captcha form
|
66
76
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
77
|
+
```ruby
|
78
|
+
def create
|
79
|
+
@comment = Comment.new(@captcha.values) #Decrypted params
|
80
|
+
if @captcha.valid? && @comment.save
|
81
|
+
redirect_to @comment
|
82
|
+
else
|
83
|
+
flash[:notice] = @captcha.error if @captcha.error
|
84
|
+
render :action => 'new'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
```
|
88
|
+
|
76
89
|
### Automated tests
|
77
90
|
|
78
91
|
To make all field ids and names predictable for tests,
|
79
92
|
simply add the following line in config/environments/test.rb
|
80
|
-
|
81
|
-
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
NegativeCaptcha.test_mode = true
|
96
|
+
```
|
82
97
|
|
83
98
|
This will ensure that a field named email will not generate a hash but a field name test-email instead.
|
84
99
|
A tool like cucumber can now bypass this security while still going through the captcha workflow.
|
@@ -87,26 +102,28 @@ A tool like cucumber can now bypass this security while still going through the
|
|
87
102
|
|
88
103
|
Modify your form to include the honeypots and other fields. You can probably leave any select, radio, and check box fields alone. The text field/text area helpers should be sufficient.
|
89
104
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
105
|
+
```erb
|
106
|
+
<% form_tag comments_path do -%>
|
107
|
+
<%= raw negative_captcha(@captcha) %>
|
108
|
+
<ul class="contact_us">
|
109
|
+
<li>
|
110
|
+
<%= negative_label_tag(@captcha, :name, 'Name:') %>
|
111
|
+
<%= negative_text_field_tag @captcha, :name %>
|
112
|
+
</li>
|
113
|
+
<li>
|
114
|
+
<%= negative_label_tag(@captcha, :email, 'Email:') %>
|
115
|
+
<%= negative_text_field_tag @captcha, :email %>
|
116
|
+
</li>
|
117
|
+
<li>
|
118
|
+
<%= negative_label_tag(@captcha, :body, 'Your Comment:') %>
|
119
|
+
<%= negative_text_area_tag @captcha, :body %>
|
120
|
+
</li>
|
121
|
+
<li>
|
122
|
+
<%= submit_tag %>
|
123
|
+
</li>
|
124
|
+
</ul>
|
125
|
+
<% end -%>
|
126
|
+
```
|
110
127
|
|
111
128
|
### Test and enjoy!
|
112
129
|
|
@@ -33,6 +33,34 @@ module ActionView
|
|
33
33
|
@template.negative_hidden_field_tag(captcha, method, options).html_safe
|
34
34
|
end
|
35
35
|
|
36
|
+
def negative_file_field(captcha, method, options = {})
|
37
|
+
html = @template.negative_file_field_tag(
|
38
|
+
captcha,
|
39
|
+
method,
|
40
|
+
options
|
41
|
+
).html_safe
|
42
|
+
|
43
|
+
if @object.errors[method].present?
|
44
|
+
html = "<div class='fieldWithErrors'>#{html}</div>"
|
45
|
+
end
|
46
|
+
|
47
|
+
html.html_safe
|
48
|
+
end
|
49
|
+
|
50
|
+
def negative_check_box_field(captcha, method, options = {})
|
51
|
+
html = @template.negative_check_box_tag(
|
52
|
+
captcha,
|
53
|
+
method,
|
54
|
+
options
|
55
|
+
).html_safe
|
56
|
+
|
57
|
+
if @object.errors[method].present?
|
58
|
+
html = "<div class='fieldWithErrors'>#{html}</div>"
|
59
|
+
end
|
60
|
+
|
61
|
+
html.html_safe
|
62
|
+
end
|
63
|
+
|
36
64
|
def negative_password_field(captcha, method, options = {})
|
37
65
|
html = @template.negative_password_field_tag(
|
38
66
|
captcha,
|
@@ -41,7 +69,7 @@ module ActionView
|
|
41
69
|
).html_safe
|
42
70
|
|
43
71
|
if @object.errors[method].present?
|
44
|
-
html = "<div class='fieldWithErrors'>#{html}</div>"
|
72
|
+
html = "<div class='fieldWithErrors'>#{html}</div>"
|
45
73
|
end
|
46
74
|
|
47
75
|
html.html_safe
|
@@ -56,7 +84,7 @@ module ActionView
|
|
56
84
|
).html_safe
|
57
85
|
|
58
86
|
if @object.errors[method].present?
|
59
|
-
html = "<div class='fieldWithErrors'>#{html}</div>"
|
87
|
+
html = "<div class='fieldWithErrors'>#{html}</div>"
|
60
88
|
end
|
61
89
|
|
62
90
|
html.html_safe
|
@@ -41,6 +41,27 @@ module ActionView
|
|
41
41
|
end.html_safe
|
42
42
|
end
|
43
43
|
|
44
|
+
def negative_file_field_tag(negative_captcha, field, options={})
|
45
|
+
file_field_tag(
|
46
|
+
negative_captcha.fields[field],
|
47
|
+
options.merge(:value => negative_captcha.values[field])
|
48
|
+
) +
|
49
|
+
content_tag('div', :style => 'position: absolute; left: -2000px;') do
|
50
|
+
file_field_tag(field, :tabindex => '999')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def negative_check_box_tag(negative_captcha, field, options={})
|
55
|
+
check_box_tag(
|
56
|
+
negative_captcha.fields[field],
|
57
|
+
negative_captcha.values[field],
|
58
|
+
options
|
59
|
+
) +
|
60
|
+
content_tag('div', :style => 'position: absolute; left: -2000px;') do
|
61
|
+
check_box_tag(field, '', :tabindex => '999')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
44
65
|
def negative_password_field_tag(negative_captcha, field, options={})
|
45
66
|
password_field_tag(
|
46
67
|
negative_captcha.fields[field],
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: negative_captcha
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-03-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|