Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Resolving CVE 2015 9284" needs to be adapted for OmniAuth 2 #1031

Open
sedubois opened this issue Feb 1, 2021 · 6 comments
Open

"Resolving CVE 2015 9284" needs to be adapted for OmniAuth 2 #1031

sedubois opened this issue Feb 1, 2021 · 6 comments

Comments

@sedubois
Copy link

sedubois commented Feb 1, 2021

Configuration

  • Provider Gem: omniauth-facebook
  • Ruby Version: 3.0.0
  • Framework: Rails 6.1.1
  • Platform: macOS

Expected Behavior

Back when using OmniAuth 1.9.1, I had written CVE-2015-9284 non-regression tests as instructed. One test asserts that ActionController::InvalidAuthenticityToken is raised when making a POST request without CSRF token.

I expected this test to continue passing after upgrading, or finding instructions in the release notes on how it should be adapted after upgrading to OmniAuth 2.

Actual Behavior

After upgrading to OmniAuth 2.0.1, this test fails as no exception is caught. However the log shows that the exception was indeed raised:

D, [2021-02-01T11:20:49.328866 #13095] DEBUG -- omniauth: (facebook) Request phase initiated.
E, [2021-02-01T11:20:49.332406 #13095] ERROR -- omniauth: (facebook) Authentication failure! ActionController::InvalidAuthenticityToken: ActionController::InvalidAuthenticityToken, ActionController::InvalidAuthenticityToken

Minitest::Assertion: ActionController::InvalidAuthenticityToken expected but nothing was raised.

To my understanding, the cause is that OmniAuth now catches the exception and sends it to its OmniAuth.config.on_failure. How should the test be adapted? Or is the new recommendation to just delete these tests?

Steps to Reproduce

Install omniauth 2.0.1, omniauth-rails_csrf_protection 1.0.0, copy and run the test linked from the Wiki (direct link).

@thatguysimon
Copy link

Having the same issue.
@sedubois Did you figure out a workaround for this?
Maybe asserting that the response is a redirect to /auth/failure?

@sedubois
Copy link
Author

sedubois commented Mar 2, 2021

@thatguysimon I've configured OmniAuth.config.on_failure to raise an error during tests:

require 'test_helper'

# Make sure that https://nvd.nist.gov/vuln/detail/CVE-2015-9284 is mitigated
class Omniauth_CVE_2015_9284_Test < ActionDispatch::IntegrationTest

  test 'GET /auth/facebook' do
    get '/auth/facebook'

    assert_response :not_found
  end

  class PostTest < ActionDispatch::IntegrationTest
    setup do
      @allow_forgery_protection = ActionController::Base.allow_forgery_protection
      ActionController::Base.allow_forgery_protection = true
      @omni_auth_test_mode = OmniAuth.config.test_mode
      OmniAuth.config.test_mode = false
      @omni_auth_on_failure = OmniAuth.config.on_failure
      OmniAuth.config.on_failure = proc { raise "test auth failure!" }
    end

    test 'POST /auth/facebook without CSRF token' do
      assert_raises("test auth failure!") do
        post '/auth/facebook'
      end
    end

    teardown do
      ActionController::Base.allow_forgery_protection = @allow_forgery_protection
      OmniAuth.config.test_mode = @omni_auth_test_mode
      OmniAuth.config.on_failure = @omni_auth_on_failure
    end
  end
end

@MothOnMars
Copy link

Thanks, @sedubois ! I added your example to the wiki page on that vulnerability:
https://github.com/omniauth/omniauth/wiki/Resolving-CVE-2015-9284#regression-testing

@MothOnMars
Copy link

MothOnMars commented Sep 2, 2022

Note: using Omniauth 2.1.0, the updated spec continues to pass even without the omniauth-rails_csrf_protection gem installed. Is that gem still required to protect against this vulnerability? If so, is there a different spec that better illustrates the remaining vulnerability to confirm the fix?

@sedubois
Copy link
Author

sedubois commented Sep 6, 2022

@MothOnMars I observe the same, the test still passes when removing omniauth-rails_csrf_protection. Does this mean the gem is not required any more? Tested with omniauth 2.1.0, omniauth-apple 1.0.2, devise 4.8.1.

@hiroshi
Copy link

hiroshi commented Dec 7, 2022

Hi, as I updated omniauth in my project to 2.x, I found same situation and I dug it some degree.

Omniauth 2.x implemented their own csrf protection, but Rails do it other way. So you need to implement your own csrf protection code or use omniauth-rails_csrf_protection #1010.
Without Rails specific implementation, POST /auth/:provider wil always fail with OmniAuth::AuthenticityError.

I updated rspec snippet I posted before:
#809 (comment)
to the following. (The issue is locked. I cannot edit even my own comment...)

The with valid authenticity_token context will fail if you don't have omniauth-rails_csrf_protection or your own OmniAuth.config.request_validation_phase.

  describe 'CVE-2015-9284' do
    describe 'GET /auth/:provider' do
      it do
        get '/auth/google_oauth2'
        expect(response).not_to have_http_status(:redirect)
      end
    end

    describe 'POST /auth/:provider without CSRF token' do
      before do
        @allow_forgery_protection = ActionController::Base.allow_forgery_protection
        ActionController::Base.allow_forgery_protection = true
      end

      after do
        ActionController::Base.allow_forgery_protection = @allow_forgery_protection
      end

      context 'with valid authenticity_token' do
        it do
          get '/'
          csrf_token = Nokogiri::HTML(response.body).at('meta[name="csrf-token"]')['content']

          post '/auth/google_oauth2', params: { authenticity_token: csrf_token }
          expect(response).to redirect_to(%r{https://accounts.google.com/o/oauth2/auth\?.*})
        end
      end

      context 'without valid authenticity_token' do
        it do
          post '/auth/google_oauth2'
          expect(response).to redirect_to(%r{/auth/failure\?.*})
        end
      end
    end
  end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants