breach-mitigation-rails 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 74c1a7de9636f721f2e92b041b3ed08a937ad32a
4
+ data.tar.gz: ae23af3cbc57389c803b998e632b0e58fc53d289
5
+ SHA512:
6
+ metadata.gz: ee4194896a9732748dedbbebc9fab2d0b1a4a882c5e67c7f2994cb9408697096408edd6a59baa56712ea74791a4a58d0a0a92e95591f65b1341f87ecd3c8a582
7
+ data.tar.gz: 2a9d8009430cb46d7597c406b71ca70d68f5a06ffbb207c1cac2870e3f1eb381205c21985c2268a52dd33574420b8cb217cf6a83cc201a924c21914184e42070
@@ -18,6 +18,8 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
+ spec.add_dependency "active_support"
22
+ spec.add_dependency "rack"
21
23
  spec.add_development_dependency "bundler", "~> 1.3"
22
24
  spec.add_development_dependency "rspec"
23
25
  spec.add_development_dependency "rake"
@@ -1,3 +1,5 @@
1
+ require 'active_support/core_ext/string/output_safety'
2
+
1
3
  module BreachMitigation
2
4
  class LengthHiding
3
5
  def initialize(app)
@@ -1,3 +1,6 @@
1
+ require 'base64'
2
+ require 'rack/utils'
3
+
1
4
  module BreachMitigation
2
5
  class MaskingSecrets
3
6
  class << self
@@ -30,9 +33,10 @@ module BreachMitigation
30
33
  # tokens that we've issued without error.
31
34
 
32
35
  if masked_token.length == AUTHENTICITY_TOKEN_LENGTH
33
- # This is actually an unmasked token
34
- Rails.logger.warn "WARNING: the client is using an unmasked authenticity token. This is expected if you have just upgraded to masked tokens, but if these messages continue long after the upgrade, then something fishy is going on."
35
- masked_token == real_csrf_token(session)
36
+ # This is actually an unmasked token. This is expected if
37
+ # you have just upgraded to masked tokens, but should stop
38
+ # happening shortly after installing this gem
39
+ compare_with_real_token masked_token, session
36
40
 
37
41
  elsif masked_token.length == AUTHENTICITY_TOKEN_LENGTH * 2
38
42
  # Split the token into the one-time pad and the encrypted
@@ -41,7 +45,7 @@ module BreachMitigation
41
45
  encrypted_csrf_token = masked_token[AUTHENTICITY_TOKEN_LENGTH..-1]
42
46
  csrf_token = xor_byte_strings(one_time_pad, encrypted_csrf_token)
43
47
 
44
- csrf_token == real_csrf_token(session)
48
+ compare_with_real_token csrf_token, session
45
49
 
46
50
  else
47
51
  false # Token is malformed
@@ -50,6 +54,11 @@ module BreachMitigation
50
54
 
51
55
  private
52
56
 
57
+ def compare_with_real_token(token, session)
58
+ # Borrow a constant-time comparison from Rack
59
+ Rack::Utils.secure_compare(token, real_csrf_token(session))
60
+ end
61
+
53
62
  def real_csrf_token(session)
54
63
  session[:_csrf_token] ||= SecureRandom.base64(AUTHENTICITY_TOKEN_LENGTH)
55
64
  Base64.strict_decode64(session[:_csrf_token])
@@ -1,3 +1,3 @@
1
1
  module BreachMitigation
2
- VERSION = "0.0.4"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -0,0 +1,49 @@
1
+ require "spec_helper"
2
+ require "breach_mitigation/masking_secrets"
3
+
4
+ describe BreachMitigation::MaskingSecrets do
5
+ let(:masking_secrets) { BreachMitigation::MaskingSecrets }
6
+
7
+ describe ".masked_authenticity_token" do
8
+ it "puts :_csrf_token into the supplied session" do
9
+ session = {}
10
+ masking_secrets.masked_authenticity_token(session)
11
+ session[:_csrf_token].should_not be_nil
12
+ end
13
+
14
+ it "returns a byte string" do
15
+ masking_secrets.masked_authenticity_token({}).should_not be nil
16
+ end
17
+ end
18
+
19
+ describe ".valid_authenticity_token?" do
20
+ let(:session) do
21
+ # Seed a session with a :_csrf_token
22
+ Hash.new.tap do |session|
23
+ masking_secrets.masked_authenticity_token(session)
24
+ end
25
+ end
26
+
27
+ it "returns true for a valid unmasked token" do
28
+ valid_unmasked = session[:_csrf_token]
29
+ masking_secrets.valid_authenticity_token?(session, valid_unmasked).should == true
30
+ end
31
+
32
+ it "returns false for an invalid unmasked token" do
33
+ masking_secrets.valid_authenticity_token?(session, SecureRandom.base64(32)).should == false
34
+ end
35
+
36
+ it "returns true for a valid masked token" do
37
+ valid_masked = masking_secrets.masked_authenticity_token(session)
38
+ masking_secrets.valid_authenticity_token?(session, valid_masked).should == true
39
+ end
40
+
41
+ it "returns false for an invalid masked token" do
42
+ masking_secrets.valid_authenticity_token?(session, SecureRandom.base64(64)).should == false
43
+ end
44
+
45
+ it "returns false for a token of the wrong length" do
46
+ masking_secrets.valid_authenticity_token?(session, SecureRandom.base64(2)).should == false
47
+ end
48
+ end
49
+ end
metadata CHANGED
@@ -1,64 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: breach-mitigation-rails
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.0.4
4
+ version: 0.1.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Bradley Buda
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-08-09 00:00:00.000000000 Z
11
+ date: 2013-11-06 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
14
+ name: active_support
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rack
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
15
36
  version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
16
44
  requirements:
17
45
  - - ~>
18
46
  - !ruby/object:Gem::Version
19
47
  version: '1.3'
20
- none: false
21
- name: bundler
22
48
  type: :development
23
49
  prerelease: false
24
- requirement: !ruby/object:Gem::Requirement
50
+ version_requirements: !ruby/object:Gem::Requirement
25
51
  requirements:
26
52
  - - ~>
27
53
  - !ruby/object:Gem::Version
28
54
  version: '1.3'
29
- none: false
30
55
  - !ruby/object:Gem::Dependency
31
- version_requirements: !ruby/object:Gem::Requirement
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
32
58
  requirements:
33
- - - ! '>='
59
+ - - '>='
34
60
  - !ruby/object:Gem::Version
35
61
  version: '0'
36
- none: false
37
- name: rspec
38
62
  type: :development
39
63
  prerelease: false
40
- requirement: !ruby/object:Gem::Requirement
64
+ version_requirements: !ruby/object:Gem::Requirement
41
65
  requirements:
42
- - - ! '>='
66
+ - - '>='
43
67
  - !ruby/object:Gem::Version
44
68
  version: '0'
45
- none: false
46
69
  - !ruby/object:Gem::Dependency
47
- version_requirements: !ruby/object:Gem::Requirement
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
48
72
  requirements:
49
- - - ! '>='
73
+ - - '>='
50
74
  - !ruby/object:Gem::Version
51
75
  version: '0'
52
- none: false
53
- name: rake
54
76
  type: :development
55
77
  prerelease: false
56
- requirement: !ruby/object:Gem::Requirement
78
+ version_requirements: !ruby/object:Gem::Requirement
57
79
  requirements:
58
- - - ! '>='
80
+ - - '>='
59
81
  - !ruby/object:Gem::Version
60
82
  version: '0'
61
- none: false
62
83
  description: Mitigates the BREACH and CRIME attacks on TLS in Rails applications
63
84
  email:
64
85
  - bradleybuda@gmail.com
@@ -79,34 +100,35 @@ files:
79
100
  - lib/breach_mitigation/railtie.rb
80
101
  - lib/breach_mitigation/version.rb
81
102
  - spec/length_hiding_spec.rb
103
+ - spec/masking_secrets_spec.rb
82
104
  - spec/spec_helper.rb
83
105
  homepage: https://github.com/meldium/breach-mitigation-rails
84
106
  licenses:
85
107
  - MIT
108
+ metadata: {}
86
109
  post_install_message:
87
110
  rdoc_options: []
88
111
  require_paths:
89
112
  - lib
90
113
  required_ruby_version: !ruby/object:Gem::Requirement
91
114
  requirements:
92
- - - ! '>='
115
+ - - '>='
93
116
  - !ruby/object:Gem::Version
94
117
  version: '0'
95
- none: false
96
118
  required_rubygems_version: !ruby/object:Gem::Requirement
97
119
  requirements:
98
- - - ! '>='
120
+ - - '>='
99
121
  - !ruby/object:Gem::Version
100
122
  version: '0'
101
- none: false
102
123
  requirements: []
103
124
  rubyforge_project:
104
- rubygems_version: 1.8.23
125
+ rubygems_version: 2.0.3
105
126
  signing_key:
106
- specification_version: 3
127
+ specification_version: 4
107
128
  summary: Uses length-hiding and CSRF token masking to make it more difficult for an
108
129
  attacker to recover plaintext from HTTP responses. See README.md for details.
109
130
  test_files:
110
131
  - spec/length_hiding_spec.rb
132
+ - spec/masking_secrets_spec.rb
111
133
  - spec/spec_helper.rb
112
134
  has_rdoc: