rack_csrf 1.0.0 → 1.0.1
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/Manifest +1 -0
- data/Rakefile +1 -1
- data/features/setup.feature +5 -0
- data/features/skip_some_routes.feature +1 -1
- data/features/step_definitions/request_steps.rb +2 -1
- data/features/step_definitions/setup_steps.rb +13 -14
- data/features/support/env.rb +12 -0
- data/features/variation_on_field_name.feature +29 -0
- data/lib/rack/csrf.rb +3 -2
- data/rack_csrf.gemspec +3 -2
- data/spec/csrf_spec.rb +2 -2
- metadata +3 -2
data/Manifest
CHANGED
@@ -13,6 +13,7 @@ features/step_definitions/request_steps.rb
|
|
13
13
|
features/step_definitions/response_steps.rb
|
14
14
|
features/step_definitions/setup_steps.rb
|
15
15
|
features/support/env.rb
|
16
|
+
features/variation_on_field_name.feature
|
16
17
|
lib/rack/csrf.rb
|
17
18
|
lib/rack/vendor/securerandom.rb
|
18
19
|
LICENSE.rdoc
|
data/Rakefile
CHANGED
@@ -11,7 +11,7 @@ Spec::Rake::SpecTask.new do |t|
|
|
11
11
|
t.spec_opts = %w(-O spec/spec.opts)
|
12
12
|
end
|
13
13
|
|
14
|
-
Echoe.new('rack_csrf', '1.0.
|
14
|
+
Echoe.new('rack_csrf', '1.0.1') do |s|
|
15
15
|
s.author = 'Emanuele Vicentini'
|
16
16
|
s.email = 'emanuele.vicentini@gmail.com'
|
17
17
|
s.summary = 'Anti-CSRF Rack middleware'
|
data/features/setup.feature
CHANGED
@@ -22,3 +22,8 @@ Feature: Setup of the middleware
|
|
22
22
|
| POST:/not_checking |
|
23
23
|
| PUT:/is_wrong |
|
24
24
|
Then I get a fully functional rack
|
25
|
+
|
26
|
+
Scenario: Setup with the :field option
|
27
|
+
Given a Rack setup with the session middleware
|
28
|
+
When I insert the anti-CSRF middleware with the :field option
|
29
|
+
Then I get a fully functional rack
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Feature: Skipping the check for some specific routes
|
2
2
|
|
3
|
-
Scenario Outline: Skipping the check for
|
3
|
+
Scenario Outline: Skipping the check for some requests
|
4
4
|
Given a Rack setup with the anti-CSRF middleware and the :skip option
|
5
5
|
| pair |
|
6
6
|
| POST:/not_checking |
|
@@ -31,7 +31,8 @@ end
|
|
31
31
|
When /^it receives a (POST|PUT|DELETE) request with the right CSRF token$/ do |http_method|
|
32
32
|
http_method.downcase!
|
33
33
|
@response = Rack::MockRequest.new(@app).send http_method.to_sym, '/',
|
34
|
-
:input => "#{Rack::Csrf.csrf_field}=right_token"
|
34
|
+
:input => "#{Rack::Csrf.csrf_field}=right_token",
|
35
|
+
'rack.session' => {'csrf.token' => 'right_token'}
|
35
36
|
end
|
36
37
|
|
37
38
|
When /^it receives a (POST|PUT|DELETE) request with the wrong CSRF token$/ do |http_method|
|
@@ -1,16 +1,6 @@
|
|
1
1
|
Given /^a Rack setup (with|without) the session middleware$/ do |prep|
|
2
2
|
@rack_builder = Rack::Builder.new
|
3
|
-
@rack_builder.use
|
4
|
-
end
|
5
|
-
|
6
|
-
class CsrfFaker
|
7
|
-
def initialize(app)
|
8
|
-
@app = app
|
9
|
-
end
|
10
|
-
def call(env)
|
11
|
-
env['rack.session']['rack.csrf'] = 'right_token'
|
12
|
-
@app.call(env)
|
13
|
-
end
|
3
|
+
@rack_builder.use FakeSession if prep == 'with'
|
14
4
|
end
|
15
5
|
|
16
6
|
# Yes, they're not as DRY as possible, but I think they're more readable than
|
@@ -18,22 +8,24 @@ end
|
|
18
8
|
|
19
9
|
Given /^a Rack setup with the anti\-CSRF middleware$/ do
|
20
10
|
Given 'a Rack setup with the session middleware'
|
21
|
-
@rack_builder.use CsrfFaker
|
22
11
|
When 'I insert the anti-CSRF middleware'
|
23
12
|
end
|
24
13
|
|
25
14
|
Given /^a Rack setup with the anti\-CSRF middleware and the :raise option$/ do
|
26
15
|
Given 'a Rack setup with the session middleware'
|
27
|
-
@rack_builder.use CsrfFaker
|
28
16
|
When 'I insert the anti-CSRF middleware with the :raise option'
|
29
17
|
end
|
30
18
|
|
31
19
|
Given /^a Rack setup with the anti\-CSRF middleware and the :skip option$/ do |table|
|
32
20
|
Given 'a Rack setup with the session middleware'
|
33
|
-
@rack_builder.use CsrfFaker
|
34
21
|
When 'I insert the anti-CSRF middleware with the :skip option', table
|
35
22
|
end
|
36
23
|
|
24
|
+
Given /^a Rack setup with the anti\-CSRF middleware and the :field option$/ do
|
25
|
+
Given 'a Rack setup with the session middleware'
|
26
|
+
When 'I insert the anti-CSRF middleware with the :field option'
|
27
|
+
end
|
28
|
+
|
37
29
|
# Yes, they're not as DRY as possible, but I think they're more readable than
|
38
30
|
# a single step definition with a few captures and more complex checkings.
|
39
31
|
|
@@ -59,6 +51,13 @@ When /^I insert the anti\-CSRF middleware with the :skip option$/ do |table|
|
|
59
51
|
@app = @rack_builder.to_app
|
60
52
|
end
|
61
53
|
|
54
|
+
When /^I insert the anti\-CSRF middleware with the :field option$/ do
|
55
|
+
@rack_builder.use Rack::Lint
|
56
|
+
@rack_builder.use Rack::Csrf, :field => 'fantasy_name'
|
57
|
+
@rack_builder.run(lambda {|env| Rack::Response.new('Hello world!').finish})
|
58
|
+
@app = @rack_builder.to_app
|
59
|
+
end
|
60
|
+
|
62
61
|
Then /^I get a fully functional rack$/ do
|
63
62
|
lambda {Rack::MockRequest.new(@app).get('/')}.should_not raise_error
|
64
63
|
end
|
data/features/support/env.rb
CHANGED
@@ -2,3 +2,15 @@ require 'rubygems'
|
|
2
2
|
require 'spec/expectations'
|
3
3
|
|
4
4
|
require File.dirname(__FILE__) + "/../../lib/rack/csrf"
|
5
|
+
|
6
|
+
# Simulated session used just to be able to insert data into it without seeing
|
7
|
+
# them wiped out.
|
8
|
+
class FakeSession
|
9
|
+
def initialize(app)
|
10
|
+
@app = app
|
11
|
+
end
|
12
|
+
def call(env)
|
13
|
+
env['rack.session'] ||= Hash.new
|
14
|
+
@app.call(env)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Feature: Customization of the field name
|
2
|
+
|
3
|
+
Scenario: GET request with CSRF token in custom field
|
4
|
+
Given a Rack setup with the anti-CSRF middleware and the :field option
|
5
|
+
When it receives a GET request with the CSRF token
|
6
|
+
Then it lets it pass untouched
|
7
|
+
|
8
|
+
Scenario Outline: Handling request with the right CSRF token in custom field
|
9
|
+
Given a Rack setup with the anti-CSRF middleware and the :field option
|
10
|
+
When it receives a <method> request with the right CSRF token
|
11
|
+
Then it lets it pass untouched
|
12
|
+
|
13
|
+
Examples:
|
14
|
+
| method |
|
15
|
+
| POST |
|
16
|
+
| PUT |
|
17
|
+
| DELETE |
|
18
|
+
|
19
|
+
Scenario Outline: Handling request with the wrong CSRF token in custom field
|
20
|
+
Given a Rack setup with the anti-CSRF middleware and the :field option
|
21
|
+
When it receives a <method> request with the wrong CSRF token
|
22
|
+
Then it responds with 417
|
23
|
+
And the response body is empty
|
24
|
+
|
25
|
+
Examples:
|
26
|
+
| method |
|
27
|
+
| POST |
|
28
|
+
| PUT |
|
29
|
+
| DELETE |
|
data/lib/rack/csrf.rb
CHANGED
@@ -24,9 +24,10 @@ module Rack
|
|
24
24
|
unless env['rack.session']
|
25
25
|
raise SessionUnavailable.new('Rack::Csrf depends on session middleware')
|
26
26
|
end
|
27
|
+
self.class.csrf_token(env)
|
27
28
|
req = Rack::Request.new(env)
|
28
29
|
untouchable = !%w(POST PUT DELETE).include?(req.request_method) ||
|
29
|
-
req.POST[self.class.csrf_field] == env['rack.session']['
|
30
|
+
req.POST[self.class.csrf_field] == env['rack.session']['csrf.token'] ||
|
30
31
|
skip_checking(req)
|
31
32
|
if untouchable
|
32
33
|
@app.call(env)
|
@@ -41,7 +42,7 @@ module Rack
|
|
41
42
|
end
|
42
43
|
|
43
44
|
def self.csrf_token(env)
|
44
|
-
env['rack.session']['
|
45
|
+
env['rack.session']['csrf.token'] ||= SecureRandom.base64(32)
|
45
46
|
end
|
46
47
|
|
47
48
|
def self.csrf_tag(env)
|
data/rack_csrf.gemspec
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack_csrf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Emanuele Vicentini
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
|
11
|
-
date: 2009-
|
11
|
+
date: 2009-05-02 00:00:00 +02:00
|
12
12
|
default_executable:
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
@@ -86,6 +86,7 @@ files:
|
|
86
86
|
- features/step_definitions/response_steps.rb
|
87
87
|
- features/step_definitions/setup_steps.rb
|
88
88
|
- features/support/env.rb
|
89
|
+
- features/variation_on_field_name.feature
|
89
90
|
- lib/rack/csrf.rb
|
90
91
|
- lib/rack/vendor/securerandom.rb
|
91
92
|
- LICENSE.rdoc
|
data/spec/csrf_spec.rb
CHANGED
@@ -26,13 +26,13 @@ describe Rack::Csrf do
|
|
26
26
|
@env['rack.session'].should be_empty
|
27
27
|
Rack::Csrf.csrf_token(@env)
|
28
28
|
@env['rack.session'].should_not be_empty
|
29
|
-
@env['rack.session']['
|
29
|
+
@env['rack.session']['csrf.token'].should_not be_empty
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'should get the token from the session if it is already there' do
|
33
33
|
@env['rack.session'].should be_empty
|
34
34
|
csrf_token = Rack::Csrf.csrf_token(@env)
|
35
|
-
csrf_token.should == @env['rack.session']['
|
35
|
+
csrf_token.should == @env['rack.session']['csrf.token']
|
36
36
|
csrf_token.should == Rack::Csrf.csrf_token(@env)
|
37
37
|
end
|
38
38
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack_csrf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Emanuele Vicentini
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-05-02 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -87,6 +87,7 @@ files:
|
|
87
87
|
- features/step_definitions/response_steps.rb
|
88
88
|
- features/step_definitions/setup_steps.rb
|
89
89
|
- features/support/env.rb
|
90
|
+
- features/variation_on_field_name.feature
|
90
91
|
- lib/rack/csrf.rb
|
91
92
|
- lib/rack/vendor/securerandom.rb
|
92
93
|
- LICENSE.rdoc
|