summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorblackst0ne <blackst0ne.ru@gmail.com>2017-06-21 17:52:54 +1100
committerDouwe Maan <douwe@selenight.nl>2017-07-26 11:05:44 +0200
commit8ce8b21f675709c884148d050663b9f2374cdc61 (patch)
tree524480e042ce4ee835a59bec0f3089e401c94913
parent29022350999ab3ddc4518f7a7647939ec2de8e09 (diff)
downloadgitlab-ce-8ce8b21f675709c884148d050663b9f2374cdc61.tar.gz
Refactor CSRF protection
-rw-r--r--changelogs/unreleased/33601-add-csrf-token-verification-to-api.yml2
-rw-r--r--config/initializers/omniauth.rb2
-rw-r--r--lib/api/helpers.rb32
-rw-r--r--lib/gitlab/request_forgery_protection.rb (renamed from lib/omni_auth/request_forgery_protection.rb)6
4 files changed, 8 insertions, 34 deletions
diff --git a/changelogs/unreleased/33601-add-csrf-token-verification-to-api.yml b/changelogs/unreleased/33601-add-csrf-token-verification-to-api.yml
index fa1a77ebcc1..88cfb99a73e 100644
--- a/changelogs/unreleased/33601-add-csrf-token-verification-to-api.yml
+++ b/changelogs/unreleased/33601-add-csrf-token-verification-to-api.yml
@@ -1,4 +1,4 @@
---
title: Add CSRF token verification to API
merge_request: 12154
-author: @blackst0ne
+author: Vitaliy @blackst0ne Klachkov
diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb
index f7fa6d1c2de..24ff3b924b5 100644
--- a/config/initializers/omniauth.rb
+++ b/config/initializers/omniauth.rb
@@ -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
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index ab5f4c865e0..b81ce75ef4f 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -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
diff --git a/lib/omni_auth/request_forgery_protection.rb b/lib/gitlab/request_forgery_protection.rb
index 69155131d8d..071a72a1f8b 100644
--- a/lib/omni_auth/request_forgery_protection.rb
+++ b/lib/gitlab/request_forgery_protection.rb
@@ -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