-
Notifications
You must be signed in to change notification settings - Fork 683
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Skip CSRF protection if a valid session token is present
- Loading branch information
Aditya Mattos
committed
Jun 2, 2020
1 parent
b75299e
commit caf27a4
Showing
5 changed files
with
87 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# frozen_string_literal: true | ||
module ShopifyApp | ||
module CsrfProtection | ||
extend ActiveSupport::Concern | ||
|
||
MissingIncludeError = Class.new(StandardError) | ||
|
||
included do | ||
unless ancestors.include?(ShopifyApp::LoginProtection) | ||
raise(MissingIncludeError, 'You must include ShopifyApp::LoginProtection before including this module.') | ||
end | ||
|
||
protect_from_forgery with: :exception, unless: :valid_session_token? | ||
end | ||
|
||
private | ||
|
||
def valid_session_token? | ||
jwt_shopify_domain.present? | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 62 additions & 0 deletions
62
test/shopify_app/controller_concerns/csrf_protection_test.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# frozen_string_literal: true | ||
|
||
class CsrfProtectionController < ActionController::Base | ||
include ShopifyApp::LoginProtection | ||
include ShopifyApp::CsrfProtection | ||
|
||
def authenticity_token | ||
render(json: { authenticity_token: form_authenticity_token }) | ||
end | ||
|
||
def csrf_test | ||
head(:ok) | ||
end | ||
end | ||
|
||
class CsrfProtectionTest < ActionDispatch::IntegrationTest | ||
setup do | ||
@authenticity_protection = ActionController::Base.allow_forgery_protection | ||
ActionController::Base.allow_forgery_protection = true | ||
Rails.application.routes.draw do | ||
get '/authenticity_token', to: 'csrf_protection#authenticity_token' | ||
post '/csrf_protection_test', to: 'csrf_protection#csrf_test' | ||
end | ||
end | ||
|
||
teardown do | ||
ActionController::Base.allow_forgery_protection = @authenticity_protection | ||
Rails.application.reload_routes! | ||
end | ||
|
||
test 'it raises an error if module is included without including ShopifyApp::LoginProtection first' do | ||
error = assert_raises ShopifyApp::CsrfProtection::MissingIncludeError do | ||
class Test | ||
include ShopifyApp::CsrfProtection | ||
end | ||
end | ||
|
||
assert_equal 'You must include ShopifyApp::LoginProtection before including this module.', error.message | ||
end | ||
|
||
test 'it raises an invalid authenticity token error if a valid session token or csrf token is not provided' do | ||
assert_raises ActionController::InvalidAuthenticityToken do | ||
post '/csrf_protection_test' | ||
end | ||
end | ||
|
||
test 'it does not raise if a valid CSRF token was provided' do | ||
get '/authenticity_token' | ||
|
||
csrf_token = JSON.parse(response.body)['authenticity_token'] | ||
|
||
post '/csrf_protection_test', headers: { 'X-CSRF-Token': csrf_token } | ||
|
||
assert_response :ok | ||
end | ||
|
||
test 'it does not raise if a valid session token was provided' do | ||
post '/csrf_protection_test', env: { 'jwt.shopify_domain': "exampleshop.myshopify.com" } | ||
|
||
assert_response :ok | ||
end | ||
end |