Skip to content

Commit 8ef80e7

Browse files
committed
First go at fixing CVE-2015-9284
1 parent 857885a commit 8ef80e7

12 files changed

+266
-67
lines changed

.rubocop.yml

+24-38
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,55 @@
1+
Layout/AccessModifierIndentation:
2+
EnforcedStyle: outdent
3+
4+
Layout/SpaceInsideHashLiteralBraces:
5+
EnforcedStyle: no_space
6+
17
Metrics/BlockNesting:
28
Max: 2
39

4-
Metrics/ClassLength:
5-
CountComments: false
6-
Max: 120
7-
8-
Metrics/PerceivedComplexity:
9-
Max: 8
10+
Metrics/LineLength:
11+
AllowURI: true
12+
Enabled: false
1013

11-
Metrics/ModuleLength:
14+
Metrics/MethodLength:
1215
CountComments: false
13-
Max: 120
16+
Max: 10
1417

1518
Metrics/ParameterLists:
16-
Max: 3
19+
Max: 4
1720
CountKeywordArgs: true
1821

19-
Metrics/AbcSize:
20-
Enabled: false
21-
2222
Style/CollectionMethods:
2323
PreferredMethods:
24-
collect: 'map'
24+
map: 'collect'
2525
reduce: 'inject'
2626
find: 'detect'
2727
find_all: 'select'
2828

2929
Style/Documentation:
3030
Enabled: false
3131

32-
Style/DotPosition:
33-
EnforcedStyle: trailing
34-
3532
Style/DoubleNegation:
3633
Enabled: false
3734

38-
Style/EachWithObject:
39-
Enabled: false
40-
41-
Style/Encoding:
35+
Style/ExpandPathArguments:
4236
Enabled: false
4337

4438
Style/HashSyntax:
4539
EnforcedStyle: hash_rockets
4640

47-
Style/Lambda:
48-
Enabled: false
49-
50-
Style/SingleSpaceBeforeFirstArg:
41+
Style/StderrPuts:
5142
Enabled: false
5243

53-
Style/SpaceAroundOperators:
54-
MultiSpaceAllowedForOperators:
55-
- "="
56-
- "=>"
57-
- "||"
58-
- "||="
59-
- "&&"
60-
- "&&="
44+
Style/StringLiterals:
45+
EnforcedStyle: single_quotes
6146

62-
Style/SpaceInsideHashLiteralBraces:
63-
EnforcedStyle: no_space
47+
Style/TrailingCommaInArguments:
48+
EnforcedStyleForMultiline: comma
6449

65-
Style/StringLiterals:
66-
EnforcedStyle: double_quotes
50+
Style/TrailingCommaInHashLiteral:
51+
EnforcedStyleForMultiline: comma
6752

68-
Style/TrivialAccessors:
69-
Enabled: false
53+
Style/TrailingCommaInArrayLiteral:
54+
EnforcedStyleForMultiline: comma
55+

.travis.yml

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
bundler_args: --without development
2+
before_install:
3+
- gem update --system
4+
- gem update bundler
5+
cache: bundler
6+
env:
7+
global:
8+
- JRUBY_OPTS="$JRUBY_OPTS --debug"
9+
language: ruby
10+
rvm:
11+
- jruby-9000
12+
- 2.3.5
13+
- 2.4.4
14+
- 2.5.3
15+
- jruby-head
16+
- ruby-head
17+
matrix:
18+
allow_failures:
19+
- rvm: jruby-head
20+
- rvm: ruby-head
21+
fast_finish: true
22+
sudo: false

Gemfile

+11-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1-
source "https://rubygems.org"
1+
# frozen_string_literal: true
22

3-
# Specify your gem's dependencies in omniauth-rails.gemspec
4-
gemspec
3+
source 'https://rubygems.org'
4+
5+
gem 'rake'
56

6-
gem "rake"
7-
gem "rubocop"
7+
group :test do
8+
gem 'coveralls', :require => false
9+
gem 'rspec', '~> 3.5.0'
10+
gem 'rubocop'
11+
end
12+
13+
gemspec

Rakefile

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
require "bundler/gem_tasks"
2-
require "rubocop/rake_task"
1+
# frozen_string_literal: true
2+
require 'bundler/gem_tasks'
3+
require 'rspec/core/rake_task'
34

4-
RuboCop::RakeTask.new
5-
6-
task :default => :rubocop
5+
RSpec::Core::RakeTask.new(:spec)
6+
task :default => :spec

lib/omiauth-rails.rb

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# frozen_string_literal: true
2+
3+
require 'omniauth-rails/version'
4+
require 'omniauth-rails/railtie'

lib/omniauth-rails/railtie.rb

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# frozen_string_literal: true
2+
require 'rails'
3+
4+
module OmniAuth
5+
module Rails
6+
class Railtie < ::Rails::Railtie
7+
initializer 'OmniAuth request_forgery_protection' do
8+
OmniAuth.config.allowed_request_methods = [:post]
9+
OmniAuth.config.before_request_phase do |env|
10+
OmniAuth::Rails::RequestForgeryProtection.call(env)
11+
end
12+
end
13+
end
14+
end
15+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# frozen_string_literal: true
2+
require 'action_controller'
3+
4+
module OmniAuth
5+
module Rails
6+
module RequestForgeryProtection
7+
class Controller < ActionController::Base
8+
protect_from_forgery :with => :exception, :prepend => true
9+
10+
rescue_from ActionController::InvalidAuthenticityToken do |e|
11+
# Log warning
12+
raise e
13+
end
14+
15+
def index
16+
head :ok
17+
end
18+
end
19+
20+
def self.app
21+
@app ||= Controller.action(:index)
22+
end
23+
24+
def self.call(env)
25+
app.call(env)
26+
end
27+
28+
def self.verified?(env)
29+
call(env)
30+
31+
true
32+
rescue ActionController::InvalidAuthenticityToken
33+
false
34+
end
35+
end
36+
end
37+
end

lib/omniauth-rails/version.rb

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1-
module OmniAuthRails
2-
VERSION = "1.0.0"
1+
# frozen_string_literal: true
2+
3+
module OmniAuth
4+
module Rails
5+
VERSION = '1.0.0'
6+
end
37
end

omniauth-rails.gemspec

+21-17
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,27 @@
1-
# coding: utf-8
2-
lib = File.expand_path("../lib", __FILE__)
1+
# frozen_string_literal: true
2+
lib = File.expand_path('../lib', __FILE__)
33
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4-
require "omniauth-rails/version"
54

6-
Gem::Specification.new do |spec|
7-
spec.name = "omniauth-rails"
8-
spec.version = OmniAuthRails::VERSION
9-
spec.authors = ["Erik Michaels-Ober", "Douwe Maan"]
10-
5+
require 'omniauth-rails/version'
116

12-
spec.description = "Ruby on Rails extensions to OmniAuth"
13-
spec.summary = spec.description
14-
spec.homepage = "https://github.com/intridea/omniauth-rails"
15-
spec.license = "MIT"
7+
Gem::Specification.new do |gem|
8+
gem.authors = ['Tom Milewski']
9+
gem.email = ['[email protected]']
10+
gem.description = 'Official Rails OmniAuth gem.'
11+
gem.summary = gem.description
12+
gem.homepage = 'https://github.com/omniauth/omniauth-rails'
13+
gem.license = 'MIT'
1614

17-
spec.files = `git ls-files -z`.split("\x0")
18-
spec.require_paths = ["lib"]
15+
gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
16+
gem.files = `git ls-files`.split("\n")
17+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18+
gem.name = 'omniauth-rails'
19+
gem.require_paths = %w[lib]
20+
gem.version = OmniAuth::Rails::VERSION
1921

20-
spec.add_dependency "omniauth"
21-
spec.add_dependency "rails"
22-
spec.add_development_dependency "bundler", "~> 1.9"
22+
gem.add_dependency 'omniauth', '~> 1.0'
23+
gem.add_dependency 'rails'
24+
gem.add_development_dependency 'rack-test'
25+
gem.add_development_dependency 'rspec', '~> 3.5'
26+
gem.add_development_dependency 'simplecov'
2327
end

spec/omniauth-rails/railtie_spec.rb

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# frozen_string_literal: true
2+
require 'spec_helper'
3+
4+
describe OmniAuth::Rails::Railtie do
5+
before do
6+
OmniAuth::Rails::Railtie.initializers.each(&:run)
7+
end
8+
9+
it 'should only allow POST requests' do
10+
expect(OmniAuth.config.allowed_request_methods).to eq([:post])
11+
end
12+
13+
it 'should only allow POST requests' do
14+
env = {}
15+
expect(OmniAuth::Rails::RequestForgeryProtection).to receive(:call).with(env)
16+
OmniAuth.config.before_request_phase.call(env)
17+
end
18+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# frozen_string_literal: true
2+
require 'spec_helper'
3+
4+
describe OmniAuth::Rails::RequestForgeryProtection do
5+
let(:csrf_token) { SecureRandom.base64(ActionController::RequestForgeryProtection::AUTHENTICITY_TOKEN_LENGTH) }
6+
let(:env) do
7+
{
8+
'rack.input' => '',
9+
'rack.session' => {
10+
:_csrf_token => csrf_token,
11+
},
12+
}
13+
end
14+
15+
describe '.call' do
16+
context 'when the request method is GET' do
17+
before do
18+
env['REQUEST_METHOD'] = 'GET'
19+
end
20+
21+
it 'does not raise an exception' do
22+
expect { described_class.call(env) }.not_to raise_exception
23+
end
24+
end
25+
26+
context 'when the request method is POST' do
27+
before do
28+
env['REQUEST_METHOD'] = 'POST'
29+
end
30+
31+
context 'when the CSRF token is valid' do
32+
before do
33+
env['HTTP_X_CSRF_TOKEN'] = csrf_token
34+
end
35+
36+
it 'does not raise an exception' do
37+
expect { described_class.call(env) }.not_to raise_exception
38+
end
39+
end
40+
41+
context 'when the CSRF token is invalid' do
42+
before do
43+
env['HTTP_X_CSRF_TOKEN'] = 'foo'
44+
end
45+
46+
it 'raises an ActionController::InvalidAuthenticityToken exception' do
47+
expect { described_class.call(env) }.to raise_exception(ActionController::InvalidAuthenticityToken)
48+
end
49+
end
50+
end
51+
end
52+
53+
describe '.verified?' do
54+
context 'when the request method is GET' do
55+
before do
56+
env['REQUEST_METHOD'] = 'GET'
57+
end
58+
59+
it 'returns true' do
60+
expect(described_class.verified?(env)).to be_truthy
61+
end
62+
end
63+
64+
context 'when the request method is POST' do
65+
before do
66+
env['REQUEST_METHOD'] = 'POST'
67+
end
68+
69+
context 'when the CSRF token is valid' do
70+
before do
71+
env['HTTP_X_CSRF_TOKEN'] = csrf_token
72+
end
73+
74+
it 'returns true' do
75+
expect(described_class.verified?(env)).to be_truthy
76+
end
77+
end
78+
79+
context 'when the CSRF token is invalid' do
80+
before do
81+
env['HTTP_X_CSRF_TOKEN'] = 'foo'
82+
end
83+
84+
it 'returns false' do
85+
expect(described_class.verified?(env)).to be_falsey
86+
end
87+
end
88+
end
89+
end
90+
end

spec/spec_helper.rb

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# frozen_string_literal: true
2+
$:.unshift File.expand_path('..', __FILE__)
3+
$:.unshift File.expand_path('../../lib', __FILE__)
4+
5+
require 'simplecov'
6+
SimpleCov.start
7+
8+
require 'rspec'
9+
require 'rack/test'
10+
require 'omniauth'
11+
12+
require 'omniauth-rails/railtie'
13+
require 'omniauth-rails/request_forgery_protection'

0 commit comments

Comments
 (0)