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 +4 -4
- data/.circleci/config.yml +4 -3
- data/.rubocop.yml +2 -0
- data/CHANGELOG.md +11 -0
- data/lib/omniauth/protect.rb +5 -2
- data/lib/omniauth/protect/middleware.rb +6 -25
- data/lib/omniauth/protect/validator.rb +69 -0
- data/lib/omniauth/protect/version.rb +4 -2
- data/omniauth-protect.gemspec +2 -2
- metadata +16 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d0323e371b865fd820a86cab6d8bc9abd2eb742b89dc48a4772ae72aea28c883
|
4
|
+
data.tar.gz: 7522ed413432d9bfcb66fd75521821e3758b2ab197aaa6701b40561e560588ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e0c1a60f0d1c58a183af0c896635220d8699e93dda19e25bf2839f104041d7c3e3c0898d1bf7712b22d9108986990c4bb895bf5431cebdbadfe9e4badc1fb1a
|
7
|
+
data.tar.gz: 0ed7d096da27e8cbe9aaafaffe34867d2fc54f15fe37fb7e0596a4c74a8aeae7ad4e1a58ec23e2da1f5fa120e0b111e168dd8d2bcddc5c1fa173ac0ca1de14a0
|
data/.circleci/config.yml
CHANGED
@@ -12,7 +12,7 @@ jobs:
|
|
12
12
|
|
13
13
|
test:
|
14
14
|
docker:
|
15
|
-
- image: circleci/ruby:2.5.
|
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.
|
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.*/
|
data/.rubocop.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -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
|
data/lib/omniauth/protect.rb
CHANGED
@@ -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/
|
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
|
-
|
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
|
data/omniauth-protect.gemspec
CHANGED
@@ -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", '~>
|
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:
|
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:
|
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:
|
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:
|
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: '
|
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: '
|
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
|
-
|
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
|