encrypted_cookie 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +3 -2
- data/Manifest +1 -1
- data/README.markdown +35 -0
- data/Rakefile +1 -1
- data/encrypted_cookie.gemspec +3 -3
- data/lib/encrypted_cookie.rb +38 -6
- data/pkg/encrypted_cookie-0.0.2.gem +0 -0
- data/spec/encrypted_cookie_spec.rb +10 -1
- metadata +5 -5
- metadata.gz.sig +1 -1
- data/test/demo.rb +0 -15
data.tar.gz.sig
CHANGED
@@ -1,2 +1,3 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
~��4r=�<'��t�;=�p*��=���
|
2
|
+
>�T(R�����z�
|
3
|
+
�@��ϱ�w����)2~�<�Z�x<���+\��S~I���k}|"���c�"��@v�40�������D4�Ƭ9k���*�����(��$���B�ֻ4�����{�ߺ#�ͦ]�4�T^h����D4�Y�0����
|
data/Manifest
CHANGED
data/README.markdown
CHANGED
@@ -0,0 +1,35 @@
|
|
1
|
+
## Encrypted session cookies for Rack (and therefore Sinatra)
|
2
|
+
|
3
|
+
The `encrypted_cookie` gem provides 128-bit-AES-encrypted, tamper-proof cookies
|
4
|
+
for Rack through the class `Rack::Session::EncryptedCookie`.
|
5
|
+
|
6
|
+
## How to use encrypted\_cookie
|
7
|
+
|
8
|
+
$ gem install encrypted_cookie
|
9
|
+
|
10
|
+
Sinatra example:
|
11
|
+
|
12
|
+
require 'sinatra'
|
13
|
+
require 'encrypted_cookie'
|
14
|
+
|
15
|
+
use Rack::Session::EncryptedCookie,
|
16
|
+
:secret => TYPE_YOUR_LONG_RANDOM_STRING_HERE*
|
17
|
+
|
18
|
+
get '/' do
|
19
|
+
session[:foo] = 'bar'
|
20
|
+
"session: " + session.inspect
|
21
|
+
end
|
22
|
+
|
23
|
+
_*_ Your `:secret` must be at least 16 bytes long and should be really random.
|
24
|
+
|
25
|
+
## Encryption and integrity protection
|
26
|
+
|
27
|
+
The cookie encryption method is 128-bit AES (with salt). Additionally, the
|
28
|
+
cookies are integrity protected with Rack's built-in HMAC support, which means
|
29
|
+
that if a user tampers with their cookie in any way, their session will
|
30
|
+
immediately be reset to `{}` (empty hash).
|
31
|
+
|
32
|
+
## Generating a good secret
|
33
|
+
|
34
|
+
require 'openssl'
|
35
|
+
puts OpenSSL::Random.random_bytes(16).inspect
|
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'rake'
|
3
3
|
require 'echoe'
|
4
4
|
|
5
|
-
Echoe.new('encrypted_cookie', '0.0.
|
5
|
+
Echoe.new('encrypted_cookie', '0.0.3') do |p|
|
6
6
|
p.description = "Encrypted session cookies for Rack"
|
7
7
|
p.url = "http://github.com/cvonkleist/encrypted_cookie"
|
8
8
|
p.author = "Christian von Kleist"
|
data/encrypted_cookie.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{encrypted_cookie}
|
5
|
-
s.version = "0.0.
|
5
|
+
s.version = "0.0.3"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Christian von Kleist"]
|
9
9
|
s.cert_chain = ["/home/cvk/.gemcert/gem-public_cert.pem"]
|
10
|
-
s.date = %q{2011-03-
|
10
|
+
s.date = %q{2011-03-03}
|
11
11
|
s.description = %q{Encrypted session cookies for Rack}
|
12
12
|
s.email = %q{cvonkleist at-a-place-called gmail.com}
|
13
13
|
s.extra_rdoc_files = ["README.markdown", "lib/encrypted_cookie.rb"]
|
14
|
-
s.files = ["Manifest", "README.markdown", "Rakefile", "encrypted_cookie.gemspec", "lib/encrypted_cookie.rb", "
|
14
|
+
s.files = ["Manifest", "README.markdown", "Rakefile", "encrypted_cookie.gemspec", "lib/encrypted_cookie.rb", "pkg/encrypted_cookie-0.0.2.gem", "spec/encrypted_cookie_spec.rb"]
|
15
15
|
s.homepage = %q{http://github.com/cvonkleist/encrypted_cookie}
|
16
16
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Encrypted_cookie", "--main", "README.markdown"]
|
17
17
|
s.require_paths = ["lib"]
|
data/lib/encrypted_cookie.rb
CHANGED
@@ -1,9 +1,29 @@
|
|
1
1
|
require 'openssl'
|
2
|
-
require 'rack/
|
2
|
+
require 'rack/request'
|
3
|
+
require 'rack/response'
|
3
4
|
|
4
5
|
module Rack
|
6
|
+
|
5
7
|
module Session
|
6
|
-
|
8
|
+
|
9
|
+
# Rack::Session::EncryptedCookie provides AES-128-encrypted, tamper-proof
|
10
|
+
# cookie-based session management.
|
11
|
+
#
|
12
|
+
# The session is Marshal'd, HMAC'd, and encrypted.
|
13
|
+
#
|
14
|
+
# Example:
|
15
|
+
#
|
16
|
+
# use Rack::Session::EncryptedCookie,
|
17
|
+
# :secret => 'change_me',
|
18
|
+
# :key => 'rack.session',
|
19
|
+
# :domain => 'foo.com',
|
20
|
+
# :path => '/',
|
21
|
+
# :expire_after => 2592000
|
22
|
+
#
|
23
|
+
# All parameters are optional except :secret.
|
24
|
+
|
25
|
+
class EncryptedCookie
|
26
|
+
|
7
27
|
def initialize(app, options={})
|
8
28
|
@app = app
|
9
29
|
@key = options[:key] || "rack.session"
|
@@ -14,14 +34,24 @@ module Rack
|
|
14
34
|
:expire_after => nil}.merge(options)
|
15
35
|
end
|
16
36
|
|
37
|
+
def call(env)
|
38
|
+
load_session(env)
|
39
|
+
status, headers, body = @app.call(env)
|
40
|
+
commit_session(env, status, headers, body)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
17
45
|
def load_session(env)
|
18
46
|
request = Rack::Request.new(env)
|
19
47
|
session_data = request.cookies[@key]
|
20
48
|
|
21
49
|
if session_data
|
22
|
-
|
23
|
-
|
24
|
-
|
50
|
+
#begin
|
51
|
+
session_data = decrypt(session_data)
|
52
|
+
session_data, digest = session_data.split("--")
|
53
|
+
session_data = nil unless digest == generate_hmac(session_data)
|
54
|
+
#rescue OpenSSL::Cipher::Cipher
|
25
55
|
end
|
26
56
|
|
27
57
|
begin
|
@@ -56,7 +86,9 @@ module Rack
|
|
56
86
|
[status, headers, body]
|
57
87
|
end
|
58
88
|
|
59
|
-
|
89
|
+
def generate_hmac(data)
|
90
|
+
OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, @secret, data)
|
91
|
+
end
|
60
92
|
|
61
93
|
def encrypt(str)
|
62
94
|
aes = OpenSSL::Cipher::Cipher.new('aes-128-cbc').encrypt
|
Binary file
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'rack/test'
|
2
2
|
require 'sinatra'
|
3
3
|
require 'rspec'
|
4
|
-
require 'ruby-debug'
|
5
4
|
require 'cgi'
|
6
5
|
require File.dirname(__FILE__) + '/../lib/encrypted_cookie'
|
7
6
|
|
@@ -81,6 +80,16 @@ describe EncryptedApp do
|
|
81
80
|
|
82
81
|
lambda { plaintext = (aes.update(crypted_text) << aes.final) }.should raise_error("bad decrypt")
|
83
82
|
end
|
83
|
+
it "should reset the session if someone messes with the crypted data" do
|
84
|
+
get '/set/foo/bar'
|
85
|
+
last_response.body.should == 'all set'
|
86
|
+
get '/'
|
87
|
+
last_response.body.should == 'session: {"foo"=>"bar"}'
|
88
|
+
|
89
|
+
rack_mock_session.cookie_jar.instance_variable_get(:@cookies).first.instance_variable_set(:@name_and_value, 'rack.session=lkjsdlfkjsd')
|
90
|
+
get '/'
|
91
|
+
last_response.body.should == 'session: {}'
|
92
|
+
end
|
84
93
|
end
|
85
94
|
|
86
95
|
describe UnencryptedApp do
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: encrypted_cookie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 3
|
10
|
+
version: 0.0.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Christian von Kleist
|
@@ -36,7 +36,7 @@ cert_chain:
|
|
36
36
|
DnOM3kD7rptG2g==
|
37
37
|
-----END CERTIFICATE-----
|
38
38
|
|
39
|
-
date: 2011-03-
|
39
|
+
date: 2011-03-03 00:00:00 -05:00
|
40
40
|
default_executable:
|
41
41
|
dependencies: []
|
42
42
|
|
@@ -55,8 +55,8 @@ files:
|
|
55
55
|
- Rakefile
|
56
56
|
- encrypted_cookie.gemspec
|
57
57
|
- lib/encrypted_cookie.rb
|
58
|
+
- pkg/encrypted_cookie-0.0.2.gem
|
58
59
|
- spec/encrypted_cookie_spec.rb
|
59
|
-
- test/demo.rb
|
60
60
|
has_rdoc: true
|
61
61
|
homepage: http://github.com/cvonkleist/encrypted_cookie
|
62
62
|
licenses: []
|
metadata.gz.sig
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
Ve��rH�����A-�*�F�%�[��$�yy���7ڻ
|
data/test/demo.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
require 'sinatra'
|
2
|
-
require '../lib/encrypted_cookie'
|
3
|
-
|
4
|
-
use Rack::Session::EncryptedCookie,
|
5
|
-
:key => 'rack.session',
|
6
|
-
:secret => 'ASDFASDFASDJFsakdfji2j3oij2o3ij4l12kj3'
|
7
|
-
|
8
|
-
get '/' do
|
9
|
-
"session = " + session.inspect
|
10
|
-
end
|
11
|
-
|
12
|
-
get '/set/:data' do
|
13
|
-
session[:data] = params[:data]
|
14
|
-
redirect '/'
|
15
|
-
end
|