Refactor CSRF protection
This commit is contained in:
parent
2902235099
commit
8ce8b21f67
4 changed files with 8 additions and 34 deletions
|
@ -1,4 +1,4 @@
|
|||
---
|
||||
title: Add CSRF token verification to API
|
||||
merge_request: 12154
|
||||
author: @blackst0ne
|
||||
author: Vitaliy @blackst0ne Klachkov
|
||||
|
|
|
@ -16,7 +16,7 @@ OmniAuth.config.allowed_request_methods = [:post]
|
|||
# In case of auto sign-in, the GET method is used (users don't get to click on a button)
|
||||
OmniAuth.config.allowed_request_methods << :get if Gitlab.config.omniauth.auto_sign_in_with_provider.present?
|
||||
OmniAuth.config.before_request_phase do |env|
|
||||
OmniAuth::RequestForgeryProtection.call(env)
|
||||
GitLab::RequestForgeryProtection.call(env)
|
||||
end
|
||||
|
||||
if Gitlab.config.omniauth.enabled
|
||||
|
|
|
@ -328,33 +328,6 @@ module API
|
|||
|
||||
private
|
||||
|
||||
def xor_byte_strings(s1, s2)
|
||||
s2_bytes = s2.bytes
|
||||
s1.each_byte.with_index { |c1, i| s2_bytes[i] ^= c1 }
|
||||
s2_bytes.pack('C*')
|
||||
end
|
||||
|
||||
# Check if CSRF tokens are equal.
|
||||
# The header token is masked.
|
||||
# So, before the comparison it must be unmasked.
|
||||
def csrf_tokens_valid?(request)
|
||||
session_token = request.session['_csrf_token']
|
||||
header_token = request.headers['X-Csrf-Token']
|
||||
|
||||
session_token = Base64.strict_decode64(session_token)
|
||||
header_token = Base64.strict_decode64(header_token)
|
||||
|
||||
# Decoded CSRF token passed from the frontend has to be 64 symbols long.
|
||||
return false if header_token.size != 64
|
||||
|
||||
header_token = xor_byte_strings(header_token[0...32], header_token[32..-1])
|
||||
|
||||
ActiveSupport::SecurityUtils.secure_compare(session_token, header_token)
|
||||
|
||||
rescue
|
||||
false
|
||||
end
|
||||
|
||||
def private_token
|
||||
params[APIGuard::PRIVATE_TOKEN_PARAM] || env[APIGuard::PRIVATE_TOKEN_HEADER]
|
||||
end
|
||||
|
@ -363,10 +336,9 @@ module API
|
|||
env['warden']
|
||||
end
|
||||
|
||||
# Check if CSRF tokens are valid.
|
||||
def verified_request?
|
||||
request = Grape::Request.new(env)
|
||||
|
||||
request.head? || request.get? || csrf_tokens_valid?(request)
|
||||
GitLab::RequestForgeryProtection.call(env)
|
||||
end
|
||||
|
||||
# Check the Rails session for valid authentication details
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
# Protects OmniAuth request phase against CSRF.
|
||||
# A module to check CSRF tokens in requests.
|
||||
# It's used in API helpers and OmniAuth.
|
||||
# Usage: GitLab::RequestForgeryProtection.call(env)
|
||||
|
||||
module OmniAuth
|
||||
module GitLab
|
||||
module RequestForgeryProtection
|
||||
class Controller < ActionController::Base
|
||||
protect_from_forgery with: :exception
|
Loading…
Reference in a new issue