Merge branch 'omniauth-csrf' into 'master'
Protect OmniAuth request phase against CSRF. Addresses #2268. See merge request !1793
This commit is contained in:
commit
c2ee828c19
7 changed files with 82 additions and 8 deletions
|
@ -42,6 +42,9 @@ v 7.11.0 (unreleased)
|
||||||
- Task lists are now usable in comments, and will show up in Markdown previews.
|
- Task lists are now usable in comments, and will show up in Markdown previews.
|
||||||
- Fix bug where avatar filenames were not actually deleted from the database during removal (Stan Hu)
|
- Fix bug where avatar filenames were not actually deleted from the database during removal (Stan Hu)
|
||||||
- Fix bug where Slack service channel was not saved in admin template settings. (Stan Hu)
|
- Fix bug where Slack service channel was not saved in admin template settings. (Stan Hu)
|
||||||
|
- Protect OmniAuth request phase against CSRF.
|
||||||
|
-
|
||||||
|
-
|
||||||
- Move snippets UI to fluid layout
|
- Move snippets UI to fluid layout
|
||||||
- Improve UI for sidebar. Increase separation between navigation and content
|
- Improve UI for sidebar. Increase separation between navigation and content
|
||||||
- Improve new project command options (Ben Bodenmiller)
|
- Improve new project command options (Ben Bodenmiller)
|
||||||
|
|
2
Gemfile
2
Gemfile
|
@ -23,7 +23,7 @@ gem "pg", group: :postgres
|
||||||
# Auth
|
# Auth
|
||||||
gem "devise", '3.2.4'
|
gem "devise", '3.2.4'
|
||||||
gem "devise-async", '0.9.0'
|
gem "devise-async", '0.9.0'
|
||||||
gem 'omniauth', "~> 1.1.3"
|
gem 'omniauth', "~> 1.2.2"
|
||||||
gem 'omniauth-google-oauth2'
|
gem 'omniauth-google-oauth2'
|
||||||
gem 'omniauth-twitter'
|
gem 'omniauth-twitter'
|
||||||
gem 'omniauth-github'
|
gem 'omniauth-github'
|
||||||
|
|
|
@ -362,9 +362,9 @@ GEM
|
||||||
rack (~> 1.2)
|
rack (~> 1.2)
|
||||||
octokit (3.7.0)
|
octokit (3.7.0)
|
||||||
sawyer (~> 0.6.0, >= 0.5.3)
|
sawyer (~> 0.6.0, >= 0.5.3)
|
||||||
omniauth (1.1.4)
|
omniauth (1.2.2)
|
||||||
hashie (>= 1.2, < 3)
|
hashie (>= 1.2, < 4)
|
||||||
rack
|
rack (~> 1.0)
|
||||||
omniauth-bitbucket (0.0.2)
|
omniauth-bitbucket (0.0.2)
|
||||||
multi_json (~> 1.7)
|
multi_json (~> 1.7)
|
||||||
omniauth (~> 1.1)
|
omniauth (~> 1.1)
|
||||||
|
@ -751,7 +751,7 @@ DEPENDENCIES
|
||||||
newrelic_rpm
|
newrelic_rpm
|
||||||
nprogress-rails
|
nprogress-rails
|
||||||
octokit (= 3.7.0)
|
octokit (= 3.7.0)
|
||||||
omniauth (~> 1.1.3)
|
omniauth (~> 1.2.2)
|
||||||
omniauth-bitbucket
|
omniauth-bitbucket
|
||||||
omniauth-github
|
omniauth-github
|
||||||
omniauth-gitlab
|
omniauth-gitlab
|
||||||
|
|
|
@ -5,6 +5,6 @@
|
||||||
- providers.each do |provider|
|
- providers.each do |provider|
|
||||||
%span.light
|
%span.light
|
||||||
- if default_providers.include?(provider)
|
- if default_providers.include?(provider)
|
||||||
= link_to oauth_image_tag(provider), omniauth_authorize_path(resource_name, provider), class: 'oauth-image-link'
|
= link_to oauth_image_tag(provider), omniauth_authorize_path(resource_name, provider), method: :post, class: 'oauth-image-link'
|
||||||
- else
|
- else
|
||||||
= link_to provider.to_s.titleize, omniauth_authorize_path(resource_name, provider), class: "btn", "data-no-turbolink" => "true"
|
= link_to provider.to_s.titleize, omniauth_authorize_path(resource_name, provider), method: :post, class: "btn", "data-no-turbolink" => "true"
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
- enabled_social_providers.each do |provider|
|
- enabled_social_providers.each do |provider|
|
||||||
.btn-group
|
.btn-group
|
||||||
= link_to oauth_image_tag(provider), omniauth_authorize_path(User, provider),
|
= link_to oauth_image_tag(provider), omniauth_authorize_path(User, provider),
|
||||||
class: "btn btn-lg #{'active' if oauth_active?(provider)}"
|
method: :post, class: "btn btn-lg #{'active' if oauth_active?(provider)}"
|
||||||
- if oauth_active?(provider)
|
- if oauth_active?(provider)
|
||||||
= link_to unlink_profile_account_path(provider: provider), method: :delete, class: 'btn btn-lg' do
|
= link_to unlink_profile_account_path(provider: provider), method: :delete, class: 'btn btn-lg' do
|
||||||
= icon('close')
|
= icon('close')
|
||||||
|
|
|
@ -10,3 +10,8 @@ if Gitlab::LDAP::Config.enabled?
|
||||||
alias_method server['provider_name'], :ldap
|
alias_method server['provider_name'], :ldap
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
OmniAuth.config.allowed_request_methods = [:post]
|
||||||
|
OmniAuth.config.before_request_phase do |env|
|
||||||
|
OmniAuth::RequestForgeryProtection.new(env).call
|
||||||
|
end
|
||||||
|
|
66
lib/omni_auth/request_forgery_protection.rb
Normal file
66
lib/omni_auth/request_forgery_protection.rb
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
# Protects OmniAuth request phase against CSRF.
|
||||||
|
|
||||||
|
module OmniAuth
|
||||||
|
# Based on ActionController::RequestForgeryProtection.
|
||||||
|
class RequestForgeryProtection
|
||||||
|
def initialize(env)
|
||||||
|
@env = env
|
||||||
|
end
|
||||||
|
|
||||||
|
def request
|
||||||
|
@request ||= ActionDispatch::Request.new(@env)
|
||||||
|
end
|
||||||
|
|
||||||
|
def session
|
||||||
|
request.session
|
||||||
|
end
|
||||||
|
|
||||||
|
def reset_session
|
||||||
|
request.reset_session
|
||||||
|
end
|
||||||
|
|
||||||
|
def params
|
||||||
|
request.params
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
verify_authenticity_token
|
||||||
|
end
|
||||||
|
|
||||||
|
def verify_authenticity_token
|
||||||
|
if !verified_request?
|
||||||
|
Rails.logger.warn "Can't verify CSRF token authenticity" if Rails.logger
|
||||||
|
handle_unverified_request
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def protect_against_forgery?
|
||||||
|
ApplicationController.allow_forgery_protection
|
||||||
|
end
|
||||||
|
|
||||||
|
def request_forgery_protection_token
|
||||||
|
ApplicationController.request_forgery_protection_token
|
||||||
|
end
|
||||||
|
|
||||||
|
def forgery_protection_strategy
|
||||||
|
ApplicationController.forgery_protection_strategy
|
||||||
|
end
|
||||||
|
|
||||||
|
def verified_request?
|
||||||
|
!protect_against_forgery? || request.get? || request.head? ||
|
||||||
|
form_authenticity_token == params[request_forgery_protection_token] ||
|
||||||
|
form_authenticity_token == request.headers['X-CSRF-Token']
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_unverified_request
|
||||||
|
forgery_protection_strategy.new(self).handle_unverified_request
|
||||||
|
end
|
||||||
|
|
||||||
|
# Sets the token value for the current session.
|
||||||
|
def form_authenticity_token
|
||||||
|
session[:_csrf_token] ||= SecureRandom.base64(32)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue