rack_csrf 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Changelog.md +12 -0
- data/README.rdoc +29 -6
- data/Rakefile +5 -3
- data/VERSION +1 -1
- data/examples/camping/Gemfile +2 -2
- data/examples/camping/app.rb +1 -1
- data/examples/cuba/Gemfile +3 -0
- data/examples/cuba/README.rdoc +11 -0
- data/examples/cuba/app.rb +17 -0
- data/examples/cuba/config-with-raise.ru +11 -0
- data/examples/cuba/config.ru +10 -0
- data/examples/cuba/views/form.erb +8 -0
- data/examples/cuba/views/form_not_working.erb +7 -0
- data/examples/cuba/views/response.erb +5 -0
- data/examples/innate/Gemfile +1 -1
- data/examples/innate/app.rb +1 -1
- data/examples/innate/view/index.erb +1 -1
- data/examples/rack/Gemfile +1 -1
- data/examples/rack/app.rb +2 -2
- data/examples/sinatra/Gemfile +1 -1
- data/examples/sinatra/app.rb +1 -1
- data/examples/sinatra/views/form.erb +1 -1
- data/features/check_only_some_specific_requests.feature +28 -0
- data/features/custom_http_methods.feature +62 -0
- data/features/empty_responses.feature +8 -6
- data/features/inspecting_also_get_requests.feature +20 -0
- data/features/raising_exception.feature +3 -4
- data/features/setup.feature +16 -0
- data/features/step_definitions/request_steps.rb +8 -13
- data/features/step_definitions/setup_steps.rb +24 -0
- data/features/variation_on_field_name.feature +8 -4
- data/features/variation_on_key_name.feature +8 -4
- data/lib/rack/csrf.rb +26 -17
- data/rack_csrf.gemspec +24 -10
- data/spec/csrf_spec.rb +110 -33
- metadata +34 -7
data/Changelog.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
# v2.3.0 (2011-10-23)
|
2
|
+
|
3
|
+
* Updated examples' Gemfiles.
|
4
|
+
* Moved to use the RDoc gem.
|
5
|
+
* new option :check_only (courtesy of [ghermeto](https://github.com/ghermeto))
|
6
|
+
* Cuba example.
|
7
|
+
* Changed request checking to look at GET+POST data.
|
8
|
+
* Added support for custom HTTP methods.
|
9
|
+
* Promoted public methods' shorter aliases to main API.
|
10
|
+
|
11
|
+
|
12
|
+
|
1
13
|
# v2.2.0 (2011-04-12)
|
2
14
|
|
3
15
|
* Simplified specs and some Cucumber's steps.
|
data/README.rdoc
CHANGED
@@ -34,6 +34,20 @@ The following options allow you to tweak Rack::Csrf.
|
|
34
34
|
|
35
35
|
Default value: false.
|
36
36
|
|
37
|
+
[<tt>:check_only</tt>]
|
38
|
+
By default, Rack::Csrf checks every POST, PUT, DELETE and PATCH request;
|
39
|
+
passing an array of HTTP method/URL (regular expressions allowed) to this
|
40
|
+
option you can change this behavior to *only* check the items on this list.
|
41
|
+
|
42
|
+
use Rack::Csrf, :check_only => ['POST:/checking', 'PUT:/me_too',
|
43
|
+
'DELETE:/cars/.*\.xml', 'PATCH:/this/.*/too']
|
44
|
+
|
45
|
+
Please, note that the regular expressions are not escaped and it is your
|
46
|
+
duty to write them correctly. Empty PATH_INFO (see Rack's spec for details)
|
47
|
+
is treated as '/' for this check.
|
48
|
+
|
49
|
+
Default value: empty.
|
50
|
+
|
37
51
|
[<tt>:skip</tt>]
|
38
52
|
By default, Rack::Csrf checks every POST, PUT, DELETE and PATCH request;
|
39
53
|
passing an array of HTTP method/URL (regular expressions allowed) to this
|
@@ -64,6 +78,15 @@ The following options allow you to tweak Rack::Csrf.
|
|
64
78
|
|
65
79
|
Default value: csrf.token
|
66
80
|
|
81
|
+
[<tt>:check_also</tt>]
|
82
|
+
By passing an array of uppercase strings to this option you can add them to
|
83
|
+
the list of HTTP methods which "mark" requests that must be searched for the
|
84
|
+
anti-forging token.
|
85
|
+
|
86
|
+
use Rack::Csrf, :check_also => %w(WHATEVER YOU WANT EVEN GET)
|
87
|
+
|
88
|
+
Default value: empty
|
89
|
+
|
67
90
|
The <tt>:browser_only</tt> option has been removed; you do not need to edit
|
68
91
|
any rackup file because Rack::Csrf simply ignores unknown options. Changes
|
69
92
|
introduced in Rack version 1.1.0 tightened the parsing of POST params, so
|
@@ -80,19 +103,19 @@ The ill devised <tt>:browser_only</tt> option could have been used to
|
|
80
103
|
The following class methods try to ease the insertion of the anti-forging
|
81
104
|
token.
|
82
105
|
|
83
|
-
[<tt>Rack::Csrf.
|
106
|
+
[<tt>Rack::Csrf.key</tt> (also <tt>Rack::Csrf.csrf_key</tt>)]
|
84
107
|
Returns the name of the key used to store/retrieve the token from the Rack
|
85
108
|
session.
|
86
109
|
|
87
|
-
[<tt>Rack::Csrf.
|
110
|
+
[<tt>Rack::Csrf.field</tt> (also <tt>Rack::Csrf.csrf_field</tt>)]
|
88
111
|
Returns the name of the field that must be present in the request.
|
89
112
|
|
90
|
-
[<tt>Rack::Csrf.
|
113
|
+
[<tt>Rack::Csrf.token(env)</tt> (also <tt>Rack::Csrf.csrf_token(env)</tt>)]
|
91
114
|
Given the request's environment, it generates a random token, stuffs it in
|
92
115
|
the session and returns it to the caller or simply retrieves the already
|
93
116
|
stored one.
|
94
117
|
|
95
|
-
[<tt>Rack::Csrf.
|
118
|
+
[<tt>Rack::Csrf.tag(env)</tt> (also <tt>Rack::Csrf.csrf_tag(env)</tt>)]
|
96
119
|
Given the request's environment, it generates a small HTML fragment to
|
97
120
|
insert the token in a standard form like an hidden input field with the
|
98
121
|
right value already entered for you.
|
@@ -107,7 +130,7 @@ framework; see the various README files for other details.
|
|
107
130
|
|
108
131
|
If you want to help:
|
109
132
|
|
110
|
-
* fork the project[
|
133
|
+
* fork the project[https://github.com/baldowl/rack_csrf] on GitHub;
|
111
134
|
* work in a topic branch;
|
112
135
|
* add features/specs for your additions or bug fixes;
|
113
136
|
* write your additions/bug fixes;
|
@@ -115,7 +138,7 @@ If you want to help:
|
|
115
138
|
* send me a pull request for the topic branch.
|
116
139
|
|
117
140
|
If you have any issue, please post them on the {project's issue
|
118
|
-
list}[
|
141
|
+
list}[https://github.com/baldowl/rack_csrf] on GitHub.
|
119
142
|
|
120
143
|
== Warning! Warning! Warning!
|
121
144
|
|
data/Rakefile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'rake/clean'
|
2
2
|
require 'cucumber/rake/task'
|
3
3
|
require 'rspec/core/rake_task'
|
4
|
-
require '
|
4
|
+
require 'rdoc/task'
|
5
5
|
require 'jeweler'
|
6
6
|
|
7
7
|
Cucumber::Rake::Task.new :features
|
@@ -14,9 +14,10 @@ task :default => :spec
|
|
14
14
|
|
15
15
|
version = File.exists?('VERSION') ? File.read('VERSION').strip : ''
|
16
16
|
|
17
|
-
|
17
|
+
RDoc::Task.new :doc do |rdoc|
|
18
18
|
rdoc.rdoc_dir = 'doc'
|
19
19
|
rdoc.title = "Rack::Csrf #{version}"
|
20
|
+
rdoc.main = 'README.rdoc'
|
20
21
|
rdoc.rdoc_files.include('README.rdoc', 'LICENSE.rdoc')
|
21
22
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
22
23
|
end
|
@@ -28,12 +29,13 @@ Jeweler::Tasks.new do |gem|
|
|
28
29
|
gem.license = 'MIT'
|
29
30
|
gem.authors = 'Emanuele Vicentini'
|
30
31
|
gem.email = 'emanuele.vicentini@gmail.com'
|
31
|
-
gem.homepage = '
|
32
|
+
gem.homepage = 'https://github.com/baldowl/rack_csrf'
|
32
33
|
gem.rubyforge_project = 'rackcsrf'
|
33
34
|
gem.add_dependency 'rack', '>= 0.9'
|
34
35
|
gem.add_development_dependency 'cucumber', '>= 0.1.13'
|
35
36
|
gem.add_development_dependency 'rack-test'
|
36
37
|
gem.add_development_dependency 'rspec', '>= 2.0.0'
|
38
|
+
gem.add_development_dependency 'rdoc', '>= 2.4.2'
|
37
39
|
gem.rdoc_options << '--line-numbers' << '--inline-source' << '--title' <<
|
38
40
|
"Rack::Csrf #{version}" << '--main' << 'README.rdoc'
|
39
41
|
gem.test_files.clear
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.3.0
|
data/examples/camping/Gemfile
CHANGED
data/examples/camping/app.rb
CHANGED
@@ -37,7 +37,7 @@ module LittleApp
|
|
37
37
|
form :action => URL(Response), :method => :post do
|
38
38
|
h1 'Spit your utterance!'
|
39
39
|
input :name => :utterance, :type => :text
|
40
|
-
text Rack::Csrf.
|
40
|
+
text Rack::Csrf.tag(@env)
|
41
41
|
p {
|
42
42
|
input :type => :submit, :value => :Send!
|
43
43
|
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
= How to use Rack::Csrf with Cuba
|
2
|
+
|
3
|
+
This is a mini Cuba application with two slightly different rackup files.
|
4
|
+
Beside Rack you only need Cuba to try them, so, assuming you have Bundler
|
5
|
+
installed, run:
|
6
|
+
|
7
|
+
$ bundle install
|
8
|
+
$ bundle exec rackup -p 3000 config.ru
|
9
|
+
$ bundle exec rackup -p 3000 config-with-raise.ru
|
10
|
+
|
11
|
+
Tested with Cuba versions listed in the Gemfile.
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Cuba.define do
|
2
|
+
on get do
|
3
|
+
on '' do
|
4
|
+
res.write render('views/form.erb')
|
5
|
+
end
|
6
|
+
|
7
|
+
on 'notworking' do
|
8
|
+
res.write render('views/form_not_working.erb')
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
on post do
|
13
|
+
on 'response', param(:utterance), param(Rack::Csrf.field) do |utterance, csrf|
|
14
|
+
res.write render('views/response.erb', :utterance => utterance, :csrf => csrf)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/examples/innate/Gemfile
CHANGED
data/examples/innate/app.rb
CHANGED
data/examples/rack/Gemfile
CHANGED
data/examples/rack/app.rb
CHANGED
@@ -3,7 +3,7 @@ class LittleApp
|
|
3
3
|
<form action="/response" method="post">
|
4
4
|
<h1>Spit your utterance!</h1>
|
5
5
|
<input type="text" name="utterance">
|
6
|
-
<%= Rack::Csrf.
|
6
|
+
<%= Rack::Csrf.tag(env) %>
|
7
7
|
<p><input type="submit" value="Send!"></p>
|
8
8
|
</form>
|
9
9
|
|
@@ -38,7 +38,7 @@ class LittleApp
|
|
38
38
|
end
|
39
39
|
elsif req.post?
|
40
40
|
utterance = req['utterance']
|
41
|
-
csrf = req[Rack::Csrf.
|
41
|
+
csrf = req[Rack::Csrf.field]
|
42
42
|
Rack::Response.new(@response.result(binding)).finish
|
43
43
|
end
|
44
44
|
end
|
data/examples/sinatra/Gemfile
CHANGED
data/examples/sinatra/app.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
Feature: Check only some specific requests
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given a rack with the anti-CSRF middleware and the :check_only option
|
5
|
+
| pair |
|
6
|
+
| POST:/check/this |
|
7
|
+
|
8
|
+
Scenario: Blocking that specific request
|
9
|
+
When it receives a POST request for /check/this without the CSRF token
|
10
|
+
Then it responds with 403
|
11
|
+
|
12
|
+
Scenario Outline: Not blocking other requests
|
13
|
+
When it receives a <method> request for <path> without the CSRF token
|
14
|
+
Then it lets it pass untouched
|
15
|
+
|
16
|
+
Examples:
|
17
|
+
| method | path |
|
18
|
+
| GET | /check/this |
|
19
|
+
| PUT | /check/this |
|
20
|
+
| PATCH | /check/this |
|
21
|
+
| DELETE | /check/this |
|
22
|
+
| CUSTOM | /check/this |
|
23
|
+
| GET | /another/one |
|
24
|
+
| POST | /another/one |
|
25
|
+
| PUT | /another/one |
|
26
|
+
| PATCH | /another/one |
|
27
|
+
| DELETE | /another/one |
|
28
|
+
| CUSTOM | /another/one |
|
@@ -0,0 +1,62 @@
|
|
1
|
+
Feature: Handling custom HTTP methods
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given a rack with the anti-CSRF middleware and the :check_also option
|
5
|
+
| method |
|
6
|
+
| ME |
|
7
|
+
| YOU |
|
8
|
+
|
9
|
+
Scenario Outline: Blocking "standard" requests without the token
|
10
|
+
When it receives a <method> request without the CSRF token
|
11
|
+
Then it responds with 403
|
12
|
+
And the response body is empty
|
13
|
+
|
14
|
+
Examples:
|
15
|
+
| method |
|
16
|
+
| POST |
|
17
|
+
| PUT |
|
18
|
+
| DELETE |
|
19
|
+
| PATCH |
|
20
|
+
|
21
|
+
Scenario Outline: Blocking "standard" requests with the wrong token
|
22
|
+
When it receives a <method> request with the wrong CSRF token
|
23
|
+
Then it responds with 403
|
24
|
+
And the response body is empty
|
25
|
+
|
26
|
+
Examples:
|
27
|
+
| method |
|
28
|
+
| POST |
|
29
|
+
| PUT |
|
30
|
+
| DELETE |
|
31
|
+
| PATCH |
|
32
|
+
|
33
|
+
Scenario Outline: Blocking requests without the token
|
34
|
+
When it receives a <method> request without the CSRF token
|
35
|
+
Then it responds with 403
|
36
|
+
And the response body is empty
|
37
|
+
|
38
|
+
Examples:
|
39
|
+
| method |
|
40
|
+
| ME |
|
41
|
+
| YOU |
|
42
|
+
|
43
|
+
Scenario Outline: Blocking requests with the wrong token
|
44
|
+
When it receives a <method> request with the wrong CSRF token
|
45
|
+
Then it responds with 403
|
46
|
+
And the response body is empty
|
47
|
+
|
48
|
+
Examples:
|
49
|
+
| method |
|
50
|
+
| ME |
|
51
|
+
| YOU |
|
52
|
+
|
53
|
+
Scenario Outline: Letting pass "unknown" and safe requests without the token
|
54
|
+
When it receives a <method> request without the CSRF token
|
55
|
+
Then it lets it pass untouched
|
56
|
+
|
57
|
+
Examples:
|
58
|
+
| method |
|
59
|
+
| HIM |
|
60
|
+
| HER |
|
61
|
+
| GET |
|
62
|
+
| OPTIONS |
|
@@ -1,17 +1,21 @@
|
|
1
1
|
Feature: Handling of the HTTP requests returning an empty response
|
2
2
|
|
3
|
-
|
3
|
+
Background:
|
4
4
|
Given a rack with the anti-CSRF middleware
|
5
|
-
|
5
|
+
|
6
|
+
Scenario: GET request with the right CSRF token
|
7
|
+
When it receives a GET request with the right CSRF token
|
8
|
+
Then it lets it pass untouched
|
9
|
+
|
10
|
+
Scenario: GET request with the wrong CSRF token
|
11
|
+
When it receives a GET request with the wrong CSRF token
|
6
12
|
Then it lets it pass untouched
|
7
13
|
|
8
14
|
Scenario: GET request without CSRF token
|
9
|
-
Given a rack with the anti-CSRF middleware
|
10
15
|
When it receives a GET request without the CSRF token
|
11
16
|
Then it lets it pass untouched
|
12
17
|
|
13
18
|
Scenario Outline: Handling request without CSRF token
|
14
|
-
Given a rack with the anti-CSRF middleware
|
15
19
|
When it receives a <method> request without the CSRF token
|
16
20
|
Then it responds with 403
|
17
21
|
And the response body is empty
|
@@ -24,7 +28,6 @@ Feature: Handling of the HTTP requests returning an empty response
|
|
24
28
|
| PATCH |
|
25
29
|
|
26
30
|
Scenario Outline: Handling request with the right CSRF token
|
27
|
-
Given a rack with the anti-CSRF middleware
|
28
31
|
When it receives a <method> request with the right CSRF token
|
29
32
|
Then it lets it pass untouched
|
30
33
|
|
@@ -36,7 +39,6 @@ Feature: Handling of the HTTP requests returning an empty response
|
|
36
39
|
| PATCH |
|
37
40
|
|
38
41
|
Scenario Outline: Handling request with the wrong CSRF token
|
39
|
-
Given a rack with the anti-CSRF middleware
|
40
42
|
When it receives a <method> request with the wrong CSRF token
|
41
43
|
Then it responds with 403
|
42
44
|
And the response body is empty
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Feature: Inspecting also GET requests
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given a rack with the anti-CSRF middleware and the :check_also option
|
5
|
+
| method |
|
6
|
+
| GET |
|
7
|
+
|
8
|
+
Scenario: GET request with the right CSRF token
|
9
|
+
When it receives a GET request with the right CSRF token
|
10
|
+
Then it lets it pass untouched
|
11
|
+
|
12
|
+
Scenario: GET request with the wrong CSRF token
|
13
|
+
When it receives a GET request with the wrong CSRF token
|
14
|
+
Then it responds with 403
|
15
|
+
And the response body is empty
|
16
|
+
|
17
|
+
Scenario: GET request without the CSRF token
|
18
|
+
When it receives a GET request without the CSRF token
|
19
|
+
Then it responds with 403
|
20
|
+
And the response body is empty
|
@@ -1,12 +1,13 @@
|
|
1
1
|
Feature: Handling of the HTTP requests raising an exception
|
2
2
|
|
3
|
-
|
3
|
+
Background:
|
4
4
|
Given a rack with the anti-CSRF middleware and the :raise option
|
5
|
+
|
6
|
+
Scenario: GET request without CSRF token
|
5
7
|
When it receives a GET request without the CSRF token
|
6
8
|
Then it lets it pass untouched
|
7
9
|
|
8
10
|
Scenario Outline: Handling request without CSRF token
|
9
|
-
Given a rack with the anti-CSRF middleware and the :raise option
|
10
11
|
When it receives a <method> request without the CSRF token
|
11
12
|
Then there is no response
|
12
13
|
And an exception is climbing up the stack
|
@@ -19,7 +20,6 @@ Feature: Handling of the HTTP requests raising an exception
|
|
19
20
|
| PATCH |
|
20
21
|
|
21
22
|
Scenario Outline: Handling request with the right CSRF token
|
22
|
-
Given a rack with the anti-CSRF middleware and the :raise option
|
23
23
|
When it receives a <method> request with the right CSRF token
|
24
24
|
Then it lets it pass untouched
|
25
25
|
|
@@ -31,7 +31,6 @@ Feature: Handling of the HTTP requests raising an exception
|
|
31
31
|
| PATCH |
|
32
32
|
|
33
33
|
Scenario Outline: Handling request with the wrong CSRF token
|
34
|
-
Given a rack with the anti-CSRF middleware and the :raise option
|
35
34
|
When it receives a <method> request with the wrong CSRF token
|
36
35
|
Then there is no response
|
37
36
|
And an exception is climbing up the stack
|
data/features/setup.feature
CHANGED
@@ -32,3 +32,19 @@ Feature: Setup of the middleware
|
|
32
32
|
Given a rack with the session middleware
|
33
33
|
When I insert the anti-CSRF middleware with the :key option
|
34
34
|
Then I get a fully functional rack
|
35
|
+
|
36
|
+
Scenario: Setup with the :check_also option
|
37
|
+
Given a rack with the session middleware
|
38
|
+
When I insert the anti-CSRF middleware with the :check_also option
|
39
|
+
| method |
|
40
|
+
| ME |
|
41
|
+
| YOU |
|
42
|
+
Then I get a fully functional rack
|
43
|
+
|
44
|
+
Scenario: Setup with the :check_only option
|
45
|
+
Given a rack with the session middleware
|
46
|
+
When I insert the anti-CSRF middleware with the :check_only option
|
47
|
+
| route |
|
48
|
+
| POST:/check/me |
|
49
|
+
| PUT:/check/this/too |
|
50
|
+
Then I get a fully functional rack
|
@@ -1,12 +1,7 @@
|
|
1
|
-
When /^it receives a GET request (with|without) the CSRF token$/ do |prep|
|
2
|
-
params = prep == 'with' ? {Rack::Csrf.csrf_field => 'whatever'} : {}
|
3
|
-
@browser.get '/', :params => params
|
4
|
-
end
|
5
|
-
|
6
1
|
# Yes, they're not as DRY as possible, but I think they're more readable than
|
7
2
|
# a single step definition with a few captures and more complex checkings.
|
8
3
|
|
9
|
-
When /^it receives a (
|
4
|
+
When /^it receives a (.*) request without the CSRF token$/ do |http_method|
|
10
5
|
begin
|
11
6
|
@browser.request '/', :method => http_method
|
12
7
|
rescue Exception => e
|
@@ -14,7 +9,7 @@ When /^it receives a (POST|PUT|DELETE|PATCH) request without the CSRF token$/ do
|
|
14
9
|
end
|
15
10
|
end
|
16
11
|
|
17
|
-
When /^it receives a (
|
12
|
+
When /^it receives a (.*) request for (.+) without the CSRF token$/ do |http_method, path|
|
18
13
|
begin
|
19
14
|
@browser.request path, :method => http_method
|
20
15
|
rescue Exception => e
|
@@ -22,22 +17,22 @@ When /^it receives a (POST|PUT|DELETE|PATCH) request for (.+) without the CSRF t
|
|
22
17
|
end
|
23
18
|
end
|
24
19
|
|
25
|
-
When /^it receives a (
|
20
|
+
When /^it receives a (.*) request with the right CSRF token$/ do |http_method|
|
26
21
|
@browser.request '/', :method => http_method,
|
27
|
-
'rack.session' => {Rack::Csrf.
|
28
|
-
:params => {Rack::Csrf.
|
22
|
+
'rack.session' => {Rack::Csrf.key => 'right_token'},
|
23
|
+
:params => {Rack::Csrf.field => 'right_token'}
|
29
24
|
end
|
30
25
|
|
31
|
-
When /^it receives a (
|
26
|
+
When /^it receives a (.*) request with the wrong CSRF token$/ do |http_method|
|
32
27
|
begin
|
33
28
|
@browser.request '/', :method => http_method,
|
34
|
-
:params => {Rack::Csrf.
|
29
|
+
:params => {Rack::Csrf.field => 'whatever'}
|
35
30
|
rescue Exception => e
|
36
31
|
@exception = e
|
37
32
|
end
|
38
33
|
end
|
39
34
|
|
40
|
-
When /^it receives a (
|
35
|
+
When /^it receives a (.*) request with neither PATH_INFO nor CSRF token$/ do |http_method|
|
41
36
|
begin
|
42
37
|
@browser.request '/doesntmatter', :method => http_method, 'PATH_INFO' => ''
|
43
38
|
rescue Exception => e
|
@@ -32,6 +32,16 @@ Given /^a rack with the anti\-CSRF middleware and the :key option$/ do
|
|
32
32
|
When 'I insert the anti-CSRF middleware with the :key option'
|
33
33
|
end
|
34
34
|
|
35
|
+
Given /^a rack with the anti\-CSRF middleware and the :check_also option$/ do |table|
|
36
|
+
Given 'a rack with the session middleware'
|
37
|
+
When 'I insert the anti-CSRF middleware with the :check_also option', table
|
38
|
+
end
|
39
|
+
|
40
|
+
Given /^a rack with the anti\-CSRF middleware and the :check_only option$/ do |table|
|
41
|
+
Given 'a rack with the session middleware'
|
42
|
+
When 'I insert the anti-CSRF middleware with the :check_only option', table
|
43
|
+
end
|
44
|
+
|
35
45
|
# Yes, they're not as DRY as possible, but I think they're more readable than
|
36
46
|
# a single step definition with a few captures and more complex checkings.
|
37
47
|
|
@@ -66,6 +76,20 @@ When /^I insert the anti\-CSRF middleware with the :key option$/ do
|
|
66
76
|
@browser = Rack::Test::Session.new(Rack::MockSession.new(@app))
|
67
77
|
end
|
68
78
|
|
79
|
+
When /^I insert the anti\-CSRF middleware with the :check_also option$/ do |table|
|
80
|
+
check_also = table.hashes.collect {|t| t.values}.flatten
|
81
|
+
@rack_builder.use Rack::Csrf, :check_also => check_also
|
82
|
+
@app = toy_app
|
83
|
+
@browser = Rack::Test::Session.new(Rack::MockSession.new(@app))
|
84
|
+
end
|
85
|
+
|
86
|
+
When /^I insert the anti\-CSRF middleware with the :check_only option$/ do |table|
|
87
|
+
must_be_checked = table.hashes.collect {|t| t.values}.flatten
|
88
|
+
@rack_builder.use Rack::Csrf, :check_only => must_be_checked
|
89
|
+
@app = toy_app
|
90
|
+
@browser = Rack::Test::Session.new(Rack::MockSession.new(@app))
|
91
|
+
end
|
92
|
+
|
69
93
|
Then /^I get a fully functional rack$/ do
|
70
94
|
expect {Rack::MockRequest.new(@app).get('/')}.to_not raise_exception
|
71
95
|
end
|
@@ -1,12 +1,17 @@
|
|
1
1
|
Feature: Customization of the field name
|
2
2
|
|
3
|
-
|
3
|
+
Background:
|
4
4
|
Given a rack with the anti-CSRF middleware and the :field option
|
5
|
-
|
5
|
+
|
6
|
+
Scenario: GET request with the right CSRF token in custom field
|
7
|
+
When it receives a GET request with the right CSRF token
|
8
|
+
Then it lets it pass untouched
|
9
|
+
|
10
|
+
Scenario: GET request with the wrong CSRF token in custom field
|
11
|
+
When it receives a GET request with the wrong CSRF token
|
6
12
|
Then it lets it pass untouched
|
7
13
|
|
8
14
|
Scenario Outline: Handling request with the right CSRF token in custom field
|
9
|
-
Given a rack with the anti-CSRF middleware and the :field option
|
10
15
|
When it receives a <method> request with the right CSRF token
|
11
16
|
Then it lets it pass untouched
|
12
17
|
|
@@ -18,7 +23,6 @@ Feature: Customization of the field name
|
|
18
23
|
| PATCH |
|
19
24
|
|
20
25
|
Scenario Outline: Handling request with the wrong CSRF token in custom field
|
21
|
-
Given a rack with the anti-CSRF middleware and the :field option
|
22
26
|
When it receives a <method> request with the wrong CSRF token
|
23
27
|
Then it responds with 403
|
24
28
|
And the response body is empty
|
@@ -1,12 +1,17 @@
|
|
1
1
|
Feature: Customization of the key name
|
2
2
|
|
3
|
-
|
3
|
+
Background:
|
4
4
|
Given a rack with the anti-CSRF middleware and the :key option
|
5
|
-
|
5
|
+
|
6
|
+
Scenario: GET request with the right CSRF token stored in custom key
|
7
|
+
When it receives a GET request with the right CSRF token
|
8
|
+
Then it lets it pass untouched
|
9
|
+
|
10
|
+
Scenario: GET request with the wrong CSRF token stored in custom key
|
11
|
+
When it receives a GET request with the wrong CSRF token
|
6
12
|
Then it lets it pass untouched
|
7
13
|
|
8
14
|
Scenario Outline: Handling request with the right CSRF token stored in custom key
|
9
|
-
Given a rack with the anti-CSRF middleware and the :key option
|
10
15
|
When it receives a <method> request with the right CSRF token
|
11
16
|
Then it lets it pass untouched
|
12
17
|
|
@@ -18,7 +23,6 @@ Feature: Customization of the key name
|
|
18
23
|
| PATCH |
|
19
24
|
|
20
25
|
Scenario Outline: Handling request with the wrong CSRF token stored in custom key
|
21
|
-
Given a rack with the anti-CSRF middleware and the :key option
|
22
26
|
When it receives a <method> request with the wrong CSRF token
|
23
27
|
Then it responds with 403
|
24
28
|
And the response body is empty
|
data/lib/rack/csrf.rb
CHANGED
@@ -17,22 +17,25 @@ module Rack
|
|
17
17
|
@app = app
|
18
18
|
|
19
19
|
@raisable = opts[:raise] || false
|
20
|
-
@
|
20
|
+
@to_be_skipped = (opts[:skip] || []).map {|r| /\A#{r}\Z/i}
|
21
|
+
@to_be_checked = (opts[:check_only] || []).map {|r| /\A#{r}\Z/i}
|
21
22
|
@@field = opts[:field] if opts[:field]
|
22
23
|
@@key = opts[:key] if opts[:key]
|
23
24
|
|
24
|
-
|
25
|
+
standard_http_methods = %w(POST PUT DELETE PATCH)
|
26
|
+
check_also = opts[:check_also] || []
|
27
|
+
@http_methods = (standard_http_methods + check_also).flatten.uniq
|
25
28
|
end
|
26
29
|
|
27
30
|
def call(env)
|
28
31
|
unless env['rack.session']
|
29
32
|
raise SessionUnavailable.new('Rack::Csrf depends on session middleware')
|
30
33
|
end
|
31
|
-
self.class.
|
34
|
+
self.class.token(env)
|
32
35
|
req = Rack::Request.new(env)
|
33
|
-
untouchable =
|
34
|
-
req.
|
35
|
-
|
36
|
+
untouchable = skip_checking(req) ||
|
37
|
+
!@http_methods.include?(req.request_method) ||
|
38
|
+
req.params[self.class.field] == env['rack.session'][self.class.key]
|
36
39
|
if untouchable
|
37
40
|
@app.call(env)
|
38
41
|
else
|
@@ -41,34 +44,40 @@ module Rack
|
|
41
44
|
end
|
42
45
|
end
|
43
46
|
|
44
|
-
def self.
|
47
|
+
def self.key
|
45
48
|
@@key
|
46
49
|
end
|
47
50
|
|
48
|
-
def self.
|
51
|
+
def self.field
|
49
52
|
@@field
|
50
53
|
end
|
51
54
|
|
52
|
-
def self.
|
53
|
-
env['rack.session'][
|
55
|
+
def self.token(env)
|
56
|
+
env['rack.session'][key] ||= SecureRandom.base64(32)
|
54
57
|
end
|
55
58
|
|
56
|
-
def self.
|
57
|
-
%Q(<input type="hidden" name="#{
|
59
|
+
def self.tag(env)
|
60
|
+
%Q(<input type="hidden" name="#{field}" value="#{token(env)}" />)
|
58
61
|
end
|
59
62
|
|
60
63
|
class << self
|
61
|
-
alias_method :
|
62
|
-
alias_method :
|
63
|
-
alias_method :
|
64
|
-
alias_method :
|
64
|
+
alias_method :csrf_key, :key
|
65
|
+
alias_method :csrf_field, :field
|
66
|
+
alias_method :csrf_token, :token
|
67
|
+
alias_method :csrf_tag, :tag
|
65
68
|
end
|
66
69
|
|
67
70
|
protected
|
68
71
|
|
69
72
|
def skip_checking request
|
73
|
+
skip = any? @to_be_skipped, request
|
74
|
+
allow = any? @to_be_checked, request
|
75
|
+
skip || (!@to_be_checked.empty? && !allow)
|
76
|
+
end
|
77
|
+
|
78
|
+
def any? list, request
|
70
79
|
pi = request.path_info.empty? ? '/' : request.path_info
|
71
|
-
|
80
|
+
list.any? do |route|
|
72
81
|
route =~ (request.request_method + ':' + pi)
|
73
82
|
end
|
74
83
|
end
|
data/rack_csrf.gemspec
CHANGED
@@ -4,14 +4,14 @@
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
|
-
s.name =
|
8
|
-
s.version = "2.
|
7
|
+
s.name = "rack_csrf"
|
8
|
+
s.version = "2.3.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Emanuele Vicentini"]
|
12
|
-
s.date =
|
13
|
-
s.description =
|
14
|
-
s.email =
|
12
|
+
s.date = "2011-10-23"
|
13
|
+
s.description = "Anti-CSRF Rack middleware"
|
14
|
+
s.email = "emanuele.vicentini@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE.rdoc",
|
17
17
|
"README.rdoc"
|
@@ -28,6 +28,14 @@ Gem::Specification.new do |s|
|
|
28
28
|
"examples/camping/README.rdoc",
|
29
29
|
"examples/camping/app.rb",
|
30
30
|
"examples/camping/config.ru",
|
31
|
+
"examples/cuba/Gemfile",
|
32
|
+
"examples/cuba/README.rdoc",
|
33
|
+
"examples/cuba/app.rb",
|
34
|
+
"examples/cuba/config-with-raise.ru",
|
35
|
+
"examples/cuba/config.ru",
|
36
|
+
"examples/cuba/views/form.erb",
|
37
|
+
"examples/cuba/views/form_not_working.erb",
|
38
|
+
"examples/cuba/views/response.erb",
|
31
39
|
"examples/innate/Gemfile",
|
32
40
|
"examples/innate/README.rdoc",
|
33
41
|
"examples/innate/app.rb",
|
@@ -49,7 +57,10 @@ Gem::Specification.new do |s|
|
|
49
57
|
"examples/sinatra/views/form.erb",
|
50
58
|
"examples/sinatra/views/form_not_working.erb",
|
51
59
|
"examples/sinatra/views/response.erb",
|
60
|
+
"features/check_only_some_specific_requests.feature",
|
61
|
+
"features/custom_http_methods.feature",
|
52
62
|
"features/empty_responses.feature",
|
63
|
+
"features/inspecting_also_get_requests.feature",
|
53
64
|
"features/raising_exception.feature",
|
54
65
|
"features/setup.feature",
|
55
66
|
"features/skip_some_routes.feature",
|
@@ -66,13 +77,13 @@ Gem::Specification.new do |s|
|
|
66
77
|
"spec/csrf_spec.rb",
|
67
78
|
"spec/spec_helper.rb"
|
68
79
|
]
|
69
|
-
s.homepage =
|
80
|
+
s.homepage = "https://github.com/baldowl/rack_csrf"
|
70
81
|
s.licenses = ["MIT"]
|
71
|
-
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Rack::Csrf 2.
|
82
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Rack::Csrf 2.3.0", "--main", "README.rdoc"]
|
72
83
|
s.require_paths = ["lib"]
|
73
|
-
s.rubyforge_project =
|
74
|
-
s.rubygems_version =
|
75
|
-
s.summary =
|
84
|
+
s.rubyforge_project = "rackcsrf"
|
85
|
+
s.rubygems_version = "1.8.11"
|
86
|
+
s.summary = "Anti-CSRF Rack middleware"
|
76
87
|
|
77
88
|
if s.respond_to? :specification_version then
|
78
89
|
s.specification_version = 3
|
@@ -82,17 +93,20 @@ Gem::Specification.new do |s|
|
|
82
93
|
s.add_development_dependency(%q<cucumber>, [">= 0.1.13"])
|
83
94
|
s.add_development_dependency(%q<rack-test>, [">= 0"])
|
84
95
|
s.add_development_dependency(%q<rspec>, [">= 2.0.0"])
|
96
|
+
s.add_development_dependency(%q<rdoc>, [">= 2.4.2"])
|
85
97
|
else
|
86
98
|
s.add_dependency(%q<rack>, [">= 0.9"])
|
87
99
|
s.add_dependency(%q<cucumber>, [">= 0.1.13"])
|
88
100
|
s.add_dependency(%q<rack-test>, [">= 0"])
|
89
101
|
s.add_dependency(%q<rspec>, [">= 2.0.0"])
|
102
|
+
s.add_dependency(%q<rdoc>, [">= 2.4.2"])
|
90
103
|
end
|
91
104
|
else
|
92
105
|
s.add_dependency(%q<rack>, [">= 0.9"])
|
93
106
|
s.add_dependency(%q<cucumber>, [">= 0.1.13"])
|
94
107
|
s.add_dependency(%q<rack-test>, [">= 0"])
|
95
108
|
s.add_dependency(%q<rspec>, [">= 2.0.0"])
|
109
|
+
s.add_dependency(%q<rdoc>, [">= 2.4.2"])
|
96
110
|
end
|
97
111
|
end
|
98
112
|
|
data/spec/csrf_spec.rb
CHANGED
@@ -1,46 +1,46 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'spec_helper.rb')
|
2
2
|
|
3
3
|
describe Rack::Csrf do
|
4
|
-
describe '
|
4
|
+
describe 'key' do
|
5
5
|
it "should be 'csrf.token' by default" do
|
6
|
-
Rack::Csrf.
|
6
|
+
Rack::Csrf.key.should == 'csrf.token'
|
7
7
|
end
|
8
8
|
|
9
9
|
it "should be the value of the :key option" do
|
10
10
|
fakeapp = lambda {|env| [200, {}, []]}
|
11
11
|
Rack::Csrf.new fakeapp, :key => 'whatever'
|
12
|
-
Rack::Csrf.
|
12
|
+
Rack::Csrf.key.should == 'whatever'
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
describe '
|
17
|
-
it 'should be the same as
|
18
|
-
Rack::Csrf.method(:
|
16
|
+
describe 'csrf_key' do
|
17
|
+
it 'should be the same as method key' do
|
18
|
+
Rack::Csrf.method(:csrf_key).should == Rack::Csrf.method(:key)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
describe '
|
22
|
+
describe 'field' do
|
23
23
|
it "should be '_csrf' by default" do
|
24
|
-
Rack::Csrf.
|
24
|
+
Rack::Csrf.field.should == '_csrf'
|
25
25
|
end
|
26
26
|
|
27
27
|
it "should be the value of :field option" do
|
28
28
|
fakeapp = lambda {|env| [200, {}, []]}
|
29
29
|
Rack::Csrf.new fakeapp, :field => 'whatever'
|
30
|
-
Rack::Csrf.
|
30
|
+
Rack::Csrf.field.should == 'whatever'
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
describe '
|
35
|
-
it 'should be the same as
|
36
|
-
Rack::Csrf.method(:
|
34
|
+
describe 'csrf_field' do
|
35
|
+
it 'should be the same as method field' do
|
36
|
+
Rack::Csrf.method(:csrf_field).should == Rack::Csrf.method(:field)
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
describe '
|
40
|
+
describe 'token(env)' do
|
41
41
|
let(:env) { {'rack.session' => {}} }
|
42
42
|
|
43
|
-
specify {Rack::Csrf.
|
43
|
+
specify {Rack::Csrf.token(env).should have_at_least(32).characters}
|
44
44
|
|
45
45
|
context 'when accessing/manipulating the session' do
|
46
46
|
before do
|
@@ -48,45 +48,45 @@ describe Rack::Csrf do
|
|
48
48
|
Rack::Csrf.new fakeapp, :key => 'whatever'
|
49
49
|
end
|
50
50
|
|
51
|
-
it 'should use the key provided by
|
51
|
+
it 'should use the key provided by method key' do
|
52
52
|
env['rack.session'].should be_empty
|
53
|
-
Rack::Csrf.
|
54
|
-
env['rack.session'][Rack::Csrf.
|
53
|
+
Rack::Csrf.token env
|
54
|
+
env['rack.session'][Rack::Csrf.key].should_not be_nil
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
58
|
context 'when the session does not already contain the token' do
|
59
59
|
it 'should store the token inside the session' do
|
60
60
|
env['rack.session'].should be_empty
|
61
|
-
|
62
|
-
|
61
|
+
token = Rack::Csrf.token(env)
|
62
|
+
token.should == env['rack.session'][Rack::Csrf.key]
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
66
66
|
context 'when the session already contains the token' do
|
67
67
|
before do
|
68
|
-
Rack::Csrf.
|
68
|
+
Rack::Csrf.token env
|
69
69
|
end
|
70
70
|
|
71
71
|
it 'should get the token from the session' do
|
72
|
-
env['rack.session'][Rack::Csrf.
|
72
|
+
env['rack.session'][Rack::Csrf.key].should == Rack::Csrf.token(env)
|
73
73
|
end
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
-
describe '
|
78
|
-
it 'should be the same as
|
79
|
-
Rack::Csrf.method(:
|
77
|
+
describe 'csrf_token(env)' do
|
78
|
+
it 'should be the same as method token(env)' do
|
79
|
+
Rack::Csrf.method(:csrf_token).should == Rack::Csrf.method(:token)
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
|
-
describe '
|
83
|
+
describe 'tag(env)' do
|
84
84
|
let(:env) { {'rack.session' => {}} }
|
85
85
|
|
86
86
|
let :tag do
|
87
87
|
fakeapp = lambda {|env| [200, {}, []]}
|
88
88
|
Rack::Csrf.new fakeapp, :field => 'whatever'
|
89
|
-
Rack::Csrf.
|
89
|
+
Rack::Csrf.tag env
|
90
90
|
end
|
91
91
|
|
92
92
|
it 'should be an input field' do
|
@@ -97,19 +97,96 @@ describe Rack::Csrf do
|
|
97
97
|
tag.should =~ /type="hidden"/
|
98
98
|
end
|
99
99
|
|
100
|
-
it "should have the
|
101
|
-
tag.should =~ /name="#{Rack::Csrf.
|
100
|
+
it "should have the name provided by method field" do
|
101
|
+
tag.should =~ /name="#{Rack::Csrf.field}"/
|
102
102
|
end
|
103
103
|
|
104
|
-
it "should have the
|
105
|
-
quoted_value = Regexp.quote %Q(value="#{Rack::Csrf.
|
104
|
+
it "should have the value provided by method token(env)" do
|
105
|
+
quoted_value = Regexp.quote %Q(value="#{Rack::Csrf.token(env)}")
|
106
106
|
tag.should =~ /#{quoted_value}/
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
110
|
-
describe '
|
111
|
-
it 'should be the same as
|
112
|
-
Rack::Csrf.method(:
|
110
|
+
describe 'csrf_tag(env)' do
|
111
|
+
it 'should be the same as method tag(env)' do
|
112
|
+
Rack::Csrf.method(:csrf_tag).should == Rack::Csrf.method(:tag)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe 'skip_checking' do
|
117
|
+
class MockReq
|
118
|
+
attr_accessor :path_info, :request_method
|
119
|
+
end
|
120
|
+
|
121
|
+
before :each do
|
122
|
+
@request = MockReq.new
|
123
|
+
@request.path_info = '/hello'
|
124
|
+
@request.request_method = 'POST'
|
125
|
+
end
|
126
|
+
|
127
|
+
context 'with empty :skip and :check_only lists' do
|
128
|
+
let(:csrf) { Rack::Csrf.new nil }
|
129
|
+
|
130
|
+
it 'should run the check, irrespective of the request' do
|
131
|
+
csrf.send(:skip_checking, @request).should be_false
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'with routes in the :skip list and nothing in the :check_only list' do
|
136
|
+
let(:csrf) { Rack::Csrf.new nil, :skip => ['POST:/hello'] }
|
137
|
+
|
138
|
+
it 'should skip the check when the request is included in the :skip list' do
|
139
|
+
csrf.send(:skip_checking, @request).should be_true
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'should run the check when the request is not in the :skip list' do
|
143
|
+
@request.path_info = '/byebye'
|
144
|
+
csrf.send(:skip_checking, @request).should be_false
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context 'with routes in the :check_only list and nothing in the :skip list' do
|
149
|
+
let(:csrf) { Rack::Csrf.new nil, :check_only => ['POST:/hello'] }
|
150
|
+
|
151
|
+
it 'should run the check when the request is included in the :check_only list' do
|
152
|
+
csrf.send(:skip_checking, @request).should be_false
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'should skip the check when the request is not in the :check_only list' do
|
156
|
+
@request.path_info = '/byebye'
|
157
|
+
csrf.send(:skip_checking, @request).should be_true
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context 'with different routes in the :skip and :check_only lists' do
|
162
|
+
let :csrf do
|
163
|
+
Rack::Csrf.new nil,
|
164
|
+
:skip => ['POST:/hello'],
|
165
|
+
:check_only => ['POST:/byebye']
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'should skip the check when the request is included in the :skip list' do
|
169
|
+
csrf.send(:skip_checking, @request).should be_true
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'should run the check when the request is included in the :check_only list' do
|
173
|
+
@request.path_info = '/byebye'
|
174
|
+
csrf.send(:skip_checking, @request).should be_false
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
context 'with the same routes in the :check_only and :skip lists' do
|
179
|
+
let :csrf do
|
180
|
+
Rack::Csrf.new nil,
|
181
|
+
:skip => ['POST:/hello'],
|
182
|
+
:check_only => ['POST:/hello']
|
183
|
+
end
|
184
|
+
|
185
|
+
context 'when the request is included in one of the list' do
|
186
|
+
it 'should ignore the :check_only list and skip the check' do
|
187
|
+
csrf.send(:skip_checking, @request).should be_true
|
188
|
+
end
|
189
|
+
end
|
113
190
|
end
|
114
191
|
end
|
115
192
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack_csrf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 3
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 2
|
8
|
-
-
|
8
|
+
- 3
|
9
9
|
- 0
|
10
|
-
version: 2.
|
10
|
+
version: 2.3.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Emanuele Vicentini
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-10-23 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: rack
|
@@ -78,6 +78,22 @@ dependencies:
|
|
78
78
|
version: 2.0.0
|
79
79
|
type: :development
|
80
80
|
version_requirements: *id004
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: rdoc
|
83
|
+
prerelease: false
|
84
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
hash: 27
|
90
|
+
segments:
|
91
|
+
- 2
|
92
|
+
- 4
|
93
|
+
- 2
|
94
|
+
version: 2.4.2
|
95
|
+
type: :development
|
96
|
+
version_requirements: *id005
|
81
97
|
description: Anti-CSRF Rack middleware
|
82
98
|
email: emanuele.vicentini@gmail.com
|
83
99
|
executables: []
|
@@ -99,6 +115,14 @@ files:
|
|
99
115
|
- examples/camping/README.rdoc
|
100
116
|
- examples/camping/app.rb
|
101
117
|
- examples/camping/config.ru
|
118
|
+
- examples/cuba/Gemfile
|
119
|
+
- examples/cuba/README.rdoc
|
120
|
+
- examples/cuba/app.rb
|
121
|
+
- examples/cuba/config-with-raise.ru
|
122
|
+
- examples/cuba/config.ru
|
123
|
+
- examples/cuba/views/form.erb
|
124
|
+
- examples/cuba/views/form_not_working.erb
|
125
|
+
- examples/cuba/views/response.erb
|
102
126
|
- examples/innate/Gemfile
|
103
127
|
- examples/innate/README.rdoc
|
104
128
|
- examples/innate/app.rb
|
@@ -120,7 +144,10 @@ files:
|
|
120
144
|
- examples/sinatra/views/form.erb
|
121
145
|
- examples/sinatra/views/form_not_working.erb
|
122
146
|
- examples/sinatra/views/response.erb
|
147
|
+
- features/check_only_some_specific_requests.feature
|
148
|
+
- features/custom_http_methods.feature
|
123
149
|
- features/empty_responses.feature
|
150
|
+
- features/inspecting_also_get_requests.feature
|
124
151
|
- features/raising_exception.feature
|
125
152
|
- features/setup.feature
|
126
153
|
- features/skip_some_routes.feature
|
@@ -136,7 +163,7 @@ files:
|
|
136
163
|
- rack_csrf.gemspec
|
137
164
|
- spec/csrf_spec.rb
|
138
165
|
- spec/spec_helper.rb
|
139
|
-
homepage:
|
166
|
+
homepage: https://github.com/baldowl/rack_csrf
|
140
167
|
licenses:
|
141
168
|
- MIT
|
142
169
|
post_install_message:
|
@@ -144,7 +171,7 @@ rdoc_options:
|
|
144
171
|
- --line-numbers
|
145
172
|
- --inline-source
|
146
173
|
- --title
|
147
|
-
- Rack::Csrf 2.
|
174
|
+
- Rack::Csrf 2.3.0
|
148
175
|
- --main
|
149
176
|
- README.rdoc
|
150
177
|
require_paths:
|
@@ -170,7 +197,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
170
197
|
requirements: []
|
171
198
|
|
172
199
|
rubyforge_project: rackcsrf
|
173
|
-
rubygems_version: 1.
|
200
|
+
rubygems_version: 1.8.11
|
174
201
|
signing_key:
|
175
202
|
specification_version: 3
|
176
203
|
summary: Anti-CSRF Rack middleware
|