rack-deadline 1.0.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.
- checksums.yaml +7 -0
- data/CHANGELOG +3 -0
- data/MIT-LICENSE +18 -0
- data/README.rdoc +71 -0
- data/Rakefile +50 -0
- data/lib/rack-deadline.rb +33 -0
- data/test/rack-deadline_test.rb +75 -0
- metadata +75 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1c5ee4aaaecaccbcf6c5cd7f391fc7f6a943f2a1
|
4
|
+
data.tar.gz: b2257b76530e894c966bd76de67f56c87d85f454
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 45cf023d81d9ac86a1b7ee2064d6658f0235c513ba57237160ada5b131248ca616b915870f6f63474b8a2dd8182d41901a06c0c7d49490014376919da7cc3ef5
|
7
|
+
data.tar.gz: f546df89e134a9c43ca3b4c40384b3cdd558710f38227364e24a1b68a298ac16aa2234d7728bb06baabeacd8002278cf2bf748d0b42f222179755b474433cc2b
|
data/CHANGELOG
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Copyright (c) 2014 Jeremy Evans
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to
|
5
|
+
deal in the Software without restriction, including without limitation the
|
6
|
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
7
|
+
sell copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
16
|
+
THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
17
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
18
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
= rack-deadline
|
2
|
+
|
3
|
+
rack-deadline is a simple rack middleware that automatically
|
4
|
+
clears sessions that have been open too long (by default,
|
5
|
+
1 day).
|
6
|
+
|
7
|
+
This is designed for use with cookie stores to mitigate the
|
8
|
+
risk of session fixation, since it is impossible to invalidate
|
9
|
+
older sessions with a pure cookie-based approach.
|
10
|
+
|
11
|
+
It is impossible to enforce a deadline with the standard rack
|
12
|
+
cookie session API. The expire_after setting is not part of the
|
13
|
+
session itself (it's part of the cookie, and not cryptographically
|
14
|
+
signed), and an attacker who has access to a previous cookie can
|
15
|
+
just omit it when making a request.
|
16
|
+
|
17
|
+
This stores a deadline inside the crytographically signed session,
|
18
|
+
and once the deadline is passed, the session will no longer be valid.
|
19
|
+
|
20
|
+
= Installation
|
21
|
+
|
22
|
+
sudo gem install rack-deadline
|
23
|
+
|
24
|
+
= Source Code
|
25
|
+
|
26
|
+
Source code is available on GitHub at https://github.com/jeremyevans/rack-deadline
|
27
|
+
|
28
|
+
= Usage
|
29
|
+
|
30
|
+
First, require the library:
|
31
|
+
|
32
|
+
require 'rack-deadline'
|
33
|
+
|
34
|
+
Then load the middleware, after you have loaded the middleware
|
35
|
+
that sets up the session:
|
36
|
+
|
37
|
+
use Rack::Session::Deadline
|
38
|
+
|
39
|
+
You can also provide options:
|
40
|
+
|
41
|
+
use Rack::Session::Deadline, :deadline=>3600, :key=>'_my_deadline'
|
42
|
+
|
43
|
+
Options:
|
44
|
+
|
45
|
+
:deadline :: The number of seconds from the start of the session until
|
46
|
+
the session is no longer valid. By default this is 86400,
|
47
|
+
or 1 day.
|
48
|
+
:key :: The hash key used inside the session to store the deadline. The
|
49
|
+
deadline is stored as an integer number of seconds from the unix
|
50
|
+
epoch.
|
51
|
+
|
52
|
+
This has been tested on both Rails and Sinatra, but should work with any
|
53
|
+
software that uses the Rack::Session::Abstract::ID API.
|
54
|
+
|
55
|
+
= Tested On
|
56
|
+
|
57
|
+
* Ruby 1.8.7
|
58
|
+
* Ruby 1.9.3
|
59
|
+
* Ruby 2.0.0
|
60
|
+
* Ruby 2.1.0
|
61
|
+
* Rubinius 2.2.3
|
62
|
+
* Rack 1.4.5
|
63
|
+
* Rack 1.5.2
|
64
|
+
|
65
|
+
= License
|
66
|
+
|
67
|
+
MIT
|
68
|
+
|
69
|
+
= Author
|
70
|
+
|
71
|
+
Jeremy Evans <code@jeremyevans.net>
|
data/Rakefile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require "rake"
|
2
|
+
require "rake/clean"
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
|
6
|
+
CLEAN.include ["rack-deadline-*.gem", "rdoc", "coverage"]
|
7
|
+
|
8
|
+
desc "Build rack-deadline gem"
|
9
|
+
task :package=>[:clean] do |p|
|
10
|
+
sh %{#{FileUtils::RUBY} -S gem build rack-deadline.gemspec}
|
11
|
+
end
|
12
|
+
|
13
|
+
### Tests
|
14
|
+
|
15
|
+
desc "Run tests"
|
16
|
+
Rake::TestTask.new do |t|
|
17
|
+
t.libs.push "lib"
|
18
|
+
t.test_files = FileList['test/*_test.rb']
|
19
|
+
t.verbose = true
|
20
|
+
end
|
21
|
+
|
22
|
+
task :default=>:test
|
23
|
+
|
24
|
+
### RDoc
|
25
|
+
|
26
|
+
RDOC_DEFAULT_OPTS = ["--quiet", "--line-numbers", "--inline-source", '--title', 'Rack::Session::Deadline: Automatically clears sessions open too long']
|
27
|
+
|
28
|
+
begin
|
29
|
+
gem 'rdoc', '= 3.12.2'
|
30
|
+
gem 'hanna-nouveau'
|
31
|
+
RDOC_DEFAULT_OPTS.concat(['-f', 'hanna'])
|
32
|
+
rescue Gem::LoadError
|
33
|
+
end
|
34
|
+
|
35
|
+
rdoc_task_class = begin
|
36
|
+
require "rdoc/task"
|
37
|
+
RDoc::Task
|
38
|
+
rescue LoadError
|
39
|
+
require "rake/rdoctask"
|
40
|
+
Rake::RDocTask
|
41
|
+
end
|
42
|
+
|
43
|
+
RDOC_OPTS = RDOC_DEFAULT_OPTS + ['--main', 'README.rdoc']
|
44
|
+
|
45
|
+
rdoc_task_class.new do |rdoc|
|
46
|
+
rdoc.rdoc_dir = "rdoc"
|
47
|
+
rdoc.options += RDOC_OPTS
|
48
|
+
rdoc.rdoc_files.add %w"README.rdoc CHANGELOG MIT-LICENSE lib/**/*.rb"
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rack/session/abstract/id'
|
2
|
+
|
3
|
+
# Rack middleware that automatically clears sessions that are open too long.
|
4
|
+
# This is designed to mitigate session fixation attacks in pure cookie-based
|
5
|
+
# session storage.
|
6
|
+
class Rack::Session::Deadline
|
7
|
+
ENV_KEY = 'rack.session'.freeze
|
8
|
+
DEFAULT_KEY = '_deadline'.freeze
|
9
|
+
DEFAULT_DEADLINE = 86400
|
10
|
+
|
11
|
+
# Configure the middleware with the given options:
|
12
|
+
# :deadline :: The maximum number of seconds a session can be open.
|
13
|
+
# :key :: the key in the session hash in which to store the deadline.
|
14
|
+
def initialize(app, opts={})
|
15
|
+
@app = app
|
16
|
+
@deadline = opts[:deadline] || DEFAULT_DEADLINE
|
17
|
+
@key = opts[:key] || DEFAULT_KEY
|
18
|
+
@time_class = opts[:time_class] || Time
|
19
|
+
end
|
20
|
+
|
21
|
+
# Before calling the app, clears the session if it has passed the deadline.
|
22
|
+
# After calling the app, set the deadline in the session if it hasn't been set yet.
|
23
|
+
def call(env)
|
24
|
+
if (session = env[ENV_KEY]) && (!session.has_key?(@key) || session[@key] < @time_class.now.to_i)
|
25
|
+
session.clear
|
26
|
+
end
|
27
|
+
res = @app.call(env)
|
28
|
+
if session
|
29
|
+
session[@key] ||= @time_class.now.to_i + @deadline
|
30
|
+
end
|
31
|
+
res
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'minitest/spec'
|
4
|
+
|
5
|
+
require 'rack/test'
|
6
|
+
require 'rack-deadline'
|
7
|
+
|
8
|
+
describe Rack::Session::Deadline do
|
9
|
+
include Rack::Test::Methods
|
10
|
+
|
11
|
+
attr_reader :app
|
12
|
+
|
13
|
+
def request
|
14
|
+
Rack::MockRequest.new(@app).get('').body
|
15
|
+
end
|
16
|
+
|
17
|
+
def time_class(&block)
|
18
|
+
Class.new do
|
19
|
+
define_method(:now) do
|
20
|
+
Class.new do
|
21
|
+
define_method(:to_i, &block)
|
22
|
+
end.new
|
23
|
+
end
|
24
|
+
end.new
|
25
|
+
end
|
26
|
+
|
27
|
+
def deadline(opts={})
|
28
|
+
@app = Rack::Session::Cookie.new(Rack::Session::Deadline.new(@app, opts), :secret=>'1')
|
29
|
+
end
|
30
|
+
|
31
|
+
before do
|
32
|
+
@app = lambda do |env|
|
33
|
+
old = env['rack.session']['foo']
|
34
|
+
new = env['rack.session']['foo'] = (old||0) + 1
|
35
|
+
[200, {'Content-Type'=>'text/html'}, ["#{old}=>#{new}"]]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should work correctly with no options" do
|
40
|
+
deadline
|
41
|
+
get('/').body.must_equal '=>1'
|
42
|
+
get('/').body.must_equal '1=>2'
|
43
|
+
get('/').body.must_equal '2=>3'
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should clear session if deadline is passed" do
|
47
|
+
i = 0
|
48
|
+
deadline(:deadline=>1, :time_class=>time_class{i})
|
49
|
+
get('/').body.must_equal '=>1'
|
50
|
+
get('/').body.must_equal '1=>2'
|
51
|
+
i = 2
|
52
|
+
get('/').body.must_equal '=>1'
|
53
|
+
get('/').body.must_equal '1=>2'
|
54
|
+
i = 4
|
55
|
+
get('/').body.must_equal '=>1'
|
56
|
+
get('/').body.must_equal '1=>2'
|
57
|
+
get('/').body.must_equal '2=>3'
|
58
|
+
i = 6
|
59
|
+
get('/').body.must_equal '=>1'
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should store deadline in given session key" do
|
63
|
+
i = 5
|
64
|
+
deadline(:key=>'foo', :time_class=>time_class{i})
|
65
|
+
get('/').body.must_equal '=>1'
|
66
|
+
i = 0
|
67
|
+
get('/').body.must_equal '1=>2'
|
68
|
+
get('/').body.must_equal '2=>3'
|
69
|
+
get('/').body.must_equal '3=>4'
|
70
|
+
get('/').body.must_equal '4=>5'
|
71
|
+
get('/').body.must_equal '5=>6'
|
72
|
+
i = 86407
|
73
|
+
get('/').body.must_equal '=>1'
|
74
|
+
end
|
75
|
+
end
|
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-deadline
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jeremy Evans
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-01-28 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: |
|
14
|
+
rack-deadline is a simple rack middleware that automatically
|
15
|
+
clears sessions that have been open too long (by default,
|
16
|
+
1 day).
|
17
|
+
|
18
|
+
This is designed for use with cookie stores to mitigate the
|
19
|
+
risk of session fixation, since it is impossible to invalidate
|
20
|
+
older sessions with a pure cookie-based approach.
|
21
|
+
|
22
|
+
It is impossible to enforce a deadline with the standard rack
|
23
|
+
cookie session API. The expire_after setting is not part of the
|
24
|
+
session itself (it's part of the cookie, and not cryptographically
|
25
|
+
signed), and an attacker who has access to a previous cookie can
|
26
|
+
just omit it when making a request.
|
27
|
+
|
28
|
+
This stores a deadline inside the crytographically signed session,
|
29
|
+
and once the deadline is passed, the session will no longer be valid.
|
30
|
+
email: code@jeremyevans.net
|
31
|
+
executables: []
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files:
|
34
|
+
- README.rdoc
|
35
|
+
- CHANGELOG
|
36
|
+
- MIT-LICENSE
|
37
|
+
files:
|
38
|
+
- CHANGELOG
|
39
|
+
- MIT-LICENSE
|
40
|
+
- README.rdoc
|
41
|
+
- Rakefile
|
42
|
+
- lib/rack-deadline.rb
|
43
|
+
- test/rack-deadline_test.rb
|
44
|
+
homepage: http://gihub.com/jeremyevans/rack-deadline
|
45
|
+
licenses:
|
46
|
+
- MIT
|
47
|
+
metadata: {}
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options:
|
50
|
+
- "--quiet"
|
51
|
+
- "--line-numbers"
|
52
|
+
- "--inline-source"
|
53
|
+
- "--title"
|
54
|
+
- 'Rack::Session::Deadline: Automatically clears sessions open too long'
|
55
|
+
- "--main"
|
56
|
+
- README.rdoc
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
requirements: []
|
70
|
+
rubyforge_project:
|
71
|
+
rubygems_version: 2.2.0
|
72
|
+
signing_key:
|
73
|
+
specification_version: 4
|
74
|
+
summary: Automatically clears sessions open too long
|
75
|
+
test_files: []
|