omniauth-protect 1.0.0 → 2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7b0f8ee48965b74bb3934bdb0b2fc9e1bb7944880223c36620547f0395b806f5
4
- data.tar.gz: f35833309948e6e37da51fc8e3f288c961d9bd39d19b0d20d228b39c98eebc7c
3
+ metadata.gz: d0323e371b865fd820a86cab6d8bc9abd2eb742b89dc48a4772ae72aea28c883
4
+ data.tar.gz: 7522ed413432d9bfcb66fd75521821e3758b2ab197aaa6701b40561e560588ba
5
5
  SHA512:
6
- metadata.gz: cf78c3c787274ac00d679295ae64f96e9ec6c84355511a90929e9cc4bc0b0e405fbcfdfe5266b4cd0ce07ecf6917f7553b7484dc38401293ed40b6d8845dc38b
7
- data.tar.gz: bdc67f0584057ef2d8240e9e89d761e484040a6100b7be354fe09dbaffa9eae5b4b16d2c42c748b4edab3e9284c910a3865530b18f19e5b7719202481e3df639
6
+ metadata.gz: 4e0c1a60f0d1c58a183af0c896635220d8699e93dda19e25bf2839f104041d7c3e3c0898d1bf7712b22d9108986990c4bb895bf5431cebdbadfe9e4badc1fb1a
7
+ data.tar.gz: 0ed7d096da27e8cbe9aaafaffe34867d2fc54f15fe37fb7e0596a4c74a8aeae7ad4e1a58ec23e2da1f5fa120e0b111e168dd8d2bcddc5c1fa173ac0ca1de14a0
@@ -12,7 +12,7 @@ jobs:
12
12
 
13
13
  test:
14
14
  docker:
15
- - image: circleci/ruby:2.5.1
15
+ - image: circleci/ruby:2.5.8
16
16
  steps:
17
17
  - checkout
18
18
  - restore_cache:
@@ -20,6 +20,7 @@ jobs:
20
20
  - run:
21
21
  name: Install Ruby gems
22
22
  command: |
23
+ gem install bundler
23
24
  bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3
24
25
  - save_cache:
25
26
  key: v1-omniauth-protect-{{ checksum "Gemfile.lock" }}
@@ -44,7 +45,7 @@ jobs:
44
45
 
45
46
  push_to_rubygems:
46
47
  docker:
47
- - image: circleci/ruby:2.5.1
48
+ - image: circleci/ruby:2.5.8
48
49
  steps:
49
50
  - checkout
50
51
  - run:
@@ -77,4 +78,4 @@ workflows:
77
78
  - /.*/
78
79
  tags:
79
80
  only:
80
- - /^v.*/
81
+ - /^v.*/
@@ -0,0 +1,2 @@
1
+ inherit_gem:
2
+ rf-stylez: ruby/rubocop.yml
@@ -0,0 +1,11 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [2.0.0] - 2020-06-16
10
+ ### Changed
11
+ - Use Rails' 5.2.4.3 CSRF token algorithm
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'base64'
2
4
  require 'rack'
3
5
 
@@ -8,7 +10,7 @@ module Omniauth
8
10
 
9
11
  @config = {
10
12
  message: '',
11
- paths: []
13
+ paths: [],
12
14
  }
13
15
 
14
16
  def self.config
@@ -29,4 +31,5 @@ module Omniauth
29
31
  end
30
32
  end
31
33
 
32
- require 'omniauth/protect/middleware'
34
+ require 'omniauth/protect/validator'
35
+ require 'omniauth/protect/middleware'
@@ -1,3 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'omniauth/protect/validator'
4
+
1
5
  module Omniauth
2
6
  module Protect
3
7
  class Middleware
@@ -17,32 +21,9 @@ module Omniauth
17
21
 
18
22
  return access_denied if !encoded_masked_token
19
23
 
20
- valid_csrf_token?(env, encoded_masked_token) ? @app.call(env) : access_denied
21
- end
22
- end
23
- # This is mostly taken & adapted from https://github.com/rails/rails/blob/v4.2.0/actionpack/lib/action_controller/metal/request_forgery_protection.rb#L276
24
- def valid_csrf_token?(env, encoded_masked_token)
25
- begin
26
- masked_token = Base64.strict_decode64(encoded_masked_token)
27
- rescue ArgumentError # encoded_masked_token is invalid Base64
28
- return false
29
- end
30
-
31
- token_length = ActionController::RequestForgeryProtection::AUTHENTICITY_TOKEN_LENGTH
32
- if masked_token.length == token_length * 2
33
- one_time_pad = masked_token[0...token_length]
34
- encrypted_csrf_token = masked_token[token_length..-1]
35
- csrf_token = one_time_pad.bytes.zip(encrypted_csrf_token.bytes).map { |(c1, c2)| c1 ^ c2 }.pack('c*')
36
- session = session(env)
37
- session[:_csrf_token] ||= SecureRandom.base64(token_length)
38
- real_csrf_token = Base64.strict_decode64(session[:_csrf_token])
39
- ActiveSupport::SecurityUtils.secure_compare(csrf_token, real_csrf_token)
24
+ Validator.new(env, encoded_masked_token).valid_csrf_token? ? @app.call(env) : access_denied
40
25
  end
41
26
  end
42
-
43
- def session(env)
44
- env['rack.session']
45
- end
46
27
  end
47
28
  end
48
- end
29
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omniauth
4
+ module Protect
5
+ class Validator
6
+ def initialize(env, encoded_masked_token)
7
+ @session = env['rack.session']
8
+ @encoded_masked_token = encoded_masked_token
9
+ end
10
+
11
+ # This is mostly taken & adapted from Rails' action_controller/metal/request_forgery_protection.rb
12
+ # We copy code from Rails in such a horrible manner because Rails doesn't really expose CSRF protection
13
+ def valid_csrf_token?
14
+ begin
15
+ masked_token = Base64.urlsafe_decode64(@encoded_masked_token)
16
+ rescue ArgumentError # @encoded_masked_token is invalid Base64
17
+ return false
18
+ end
19
+
20
+ token_length = ActionController::RequestForgeryProtection::AUTHENTICITY_TOKEN_LENGTH
21
+
22
+ if masked_token.length == token_length * 2
23
+ csrf_token = unmask_token(masked_token, token_length)
24
+
25
+ real_token = real_csrf_token(token_length)
26
+ global_token = global_csrf_token(real_token)
27
+
28
+ compare_tokens(csrf_token, real_token) || compare_tokens(csrf_token, global_token)
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def compare_tokens(token, other)
35
+ ActiveSupport::SecurityUtils.fixed_length_secure_compare(token, other)
36
+ end
37
+
38
+ def unmask_token(masked_token, token_length)
39
+ one_time_pad = masked_token[0...token_length]
40
+ encrypted_csrf_token = masked_token[token_length..-1]
41
+ xor_byte_strings(one_time_pad, encrypted_csrf_token)
42
+ end
43
+
44
+ def xor_byte_strings(s1, s2) # :doc:
45
+ s2 = s2.dup
46
+ size = s1.bytesize
47
+ i = 0
48
+ while i < size
49
+ s2.setbyte(i, s1.getbyte(i) ^ s2.getbyte(i))
50
+ i += 1
51
+ end
52
+ s2
53
+ end
54
+
55
+ def real_csrf_token(token_length)
56
+ @session[:_csrf_token] ||= SecureRandom.urlsafe_base64(token_length, padding: false)
57
+ Base64.urlsafe_decode64(@session[:_csrf_token])
58
+ end
59
+
60
+ def global_csrf_token(real_token)
61
+ OpenSSL::HMAC.digest(
62
+ OpenSSL::Digest::SHA256.new,
63
+ real_token,
64
+ '!real_csrf_token'
65
+ )
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Omniauth
2
4
  module Protect
3
- VERSION = '1.0.0'
5
+ VERSION = '2.0.0'
4
6
  end
5
- end
7
+ end
@@ -23,10 +23,10 @@ Gem::Specification.new do |spec|
23
23
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
24
  spec.require_paths = ["lib"]
25
25
 
26
- spec.add_runtime_dependency 'actionpack'
26
+ spec.add_runtime_dependency 'actionpack', '>= 5.2.4.3', '< 6'
27
27
  spec.add_runtime_dependency 'rack'
28
28
 
29
- spec.add_development_dependency "bundler", '~> 1.10'
29
+ spec.add_development_dependency "bundler", '~> 2'
30
30
  spec.add_development_dependency "rake", "~> 10.0"
31
31
  spec.add_development_dependency "rspec", "~> 3.0"
32
32
  spec.add_development_dependency 'byebug'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniauth-protect
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Serdar Dogruyol
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-05-08 00:00:00.000000000 Z
11
+ date: 2020-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -16,14 +16,20 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: 5.2.4.3
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '6'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
27
  - - ">="
25
28
  - !ruby/object:Gem::Version
26
- version: '0'
29
+ version: 5.2.4.3
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '6'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: rack
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -44,14 +50,14 @@ dependencies:
44
50
  requirements:
45
51
  - - "~>"
46
52
  - !ruby/object:Gem::Version
47
- version: '1.10'
53
+ version: '2'
48
54
  type: :development
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
51
57
  requirements:
52
58
  - - "~>"
53
59
  - !ruby/object:Gem::Version
54
- version: '1.10'
60
+ version: '2'
55
61
  - !ruby/object:Gem::Dependency
56
62
  name: rake
57
63
  requirement: !ruby/object:Gem::Requirement
@@ -118,7 +124,9 @@ files:
118
124
  - ".circleci/config.yml"
119
125
  - ".gitignore"
120
126
  - ".rspec"
127
+ - ".rubocop.yml"
121
128
  - ".travis.yml"
129
+ - CHANGELOG.md
122
130
  - Gemfile
123
131
  - LICENSE.txt
124
132
  - README.md
@@ -127,6 +135,7 @@ files:
127
135
  - bin/setup
128
136
  - lib/omniauth/protect.rb
129
137
  - lib/omniauth/protect/middleware.rb
138
+ - lib/omniauth/protect/validator.rb
130
139
  - lib/omniauth/protect/version.rb
131
140
  - omniauth-protect.gemspec
132
141
  homepage: https://github.com/rainforestapp/omniauth-protect
@@ -148,8 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
148
157
  - !ruby/object:Gem::Version
149
158
  version: '0'
150
159
  requirements: []
151
- rubyforge_project:
152
- rubygems_version: 2.7.7
160
+ rubygems_version: 3.0.3
153
161
  signing_key:
154
162
  specification_version: 4
155
163
  summary: Protect Omniauth from request phase CSRF