CVE-2013-4562 (published 2014-05-13T15:55Z)

The omniauth-facebook gem 1.4.1 before 1.5.0 does not properly store the session parameter, which allows remote attackers to conduct cross-site request forgery (CSRF) attacks via the state parameter.

Severity: MEDIUM
CVSS v2 base score: 6.8 (AV:N/AC:M/Au:N/C:P/I:P/A:P)

Weakness information:
cwe_id: CWE-352
cwe_name: Cross-Site Request Forgery (CSRF)
description: The web application does not, or can not, sufficiently verify whether a well-formed, valid, consistent request was intentionally provided by the user who submitted the request.
extended_description: When a web server is designed to receive a request from a client without any mechanism for verifying that it was intentionally sent, then it might be possible for an attacker to trick a client into making an unintentional request to the web server which will be treated as an authentic request. This can be done via a URL, image load, XMLHttpRequest, etc. and can result in exposure of data or unintended code execution.
         

Fix information:
repo_url: https://github.com/mkdynamic/omniauth-facebook
commit_details: repo_url: https://github.com/mkdynamic/omniauth-facebook
author: Mark Dodwell
author_date: 2013-11-12 13:15:58-08:00
msg: fix CSRF vulnerability. prepare 1.5.0 release
repository: repo_url: https://github.com/mkdynamic/omniauth-facebook
repo_name: simi/omniauth-facebook
description: Facebook OAuth2 Strategy for OmniAuth
repo_language: Ruby
owner: mkdynamic
file_changes: filename: README.md
change_type: ModificationType.MODIFY
diff: @@ -52,8 +52,6 @@ end
 
 If you want to set the `display` format or `scope` on a per-request basis, you can just pass it to the OmniAuth request phase URL, for example: `/auth/facebook?display=popup` or `/auth/facebook?scope=email`.
 
-You can also pass through a `state` param which will be passed along to the callback url.
-
 ### Custom Callback URL/Path
 
 You can set a custom `callback_url` or `callback_path` option to override the default value. See [OmniAuth::Strategy#callback_url](https://github.com/intridea/omniauth/blob/master/lib/omniauth/strategy.rb#L411) for more details on the default.

programming_language: Markdown
filename: version.rb
change_type: ModificationType.MODIFY
diff: @@ -1,5 +1,5 @@
 module OmniAuth
   module Facebook
-    VERSION = "1.4.1"
+    VERSION = "1.5.0"
   end
 end

programming_language: Ruby
filename: facebook.rb
change_type: ModificationType.MODIFY
diff: @@ -112,7 +112,7 @@ module OmniAuth
       end
 
       ##
-      # You can pass +display+, +state+ or +scope+ params to the auth request, if
+      # You can pass +display+ or +scope+ params to the auth request, if
       # you need to set them dynamically. You can also set these options
       # in the OmniAuth config :authorize_params option.
       #
@@ -120,12 +120,9 @@ module OmniAuth
       #
       def authorize_params
         super.tap do |params|
-          %w[display state scope].each do |v|
+          %w[display scope].each do |v|
             if request.params[v]
               params[v.to_sym] = request.params[v]
-
-              # to support omniauth-oauth2's auto csrf protection
-              session['omniauth.state'] = params[:state] if v == 'state'
             end
           end
 

programming_language: Ruby
filename: shared_examples.rb
change_type: ModificationType.MODIFY
diff: @@ -50,20 +50,20 @@ module OAuth2StrategyTests
       assert_equal strategy.authorize_params['state'], strategy.session['omniauth.state']
     end
 
-    test 'should store state in the session when present in authorize params vs. a random one' do
+    test 'should not store state in the session when present in authorize params vs. a random one' do
       @options = { :authorize_params => { :state => 'bar' } }
       refute_empty strategy.authorize_params['state']
-      assert_equal 'bar', strategy.authorize_params[:state]
+      refute_equal 'bar', strategy.authorize_params[:state]
       refute_empty strategy.session['omniauth.state']
-      assert_equal 'bar', strategy.session['omniauth.state']
+      refute_equal 'bar', strategy.session['omniauth.state']
     end
 
-    test 'should store state in the session when present in request params vs. a random one' do
+    test 'should not store state in the session when present in request params vs. a random one' do
       @request.stubs(:params).returns({ 'state' => 'foo' })
       refute_empty strategy.authorize_params['state']
-      assert_equal 'foo', strategy.authorize_params[:state]
+      refute_equal 'foo', strategy.authorize_params[:state]
       refute_empty strategy.session['omniauth.state']
-      assert_equal 'foo', strategy.session['omniauth.state']
+      refute_equal 'foo', strategy.session['omniauth.state']
     end
   end
 

programming_language: Ruby
filename: test.rb
change_type: ModificationType.MODIFY
diff: @@ -56,12 +56,6 @@ class AuthorizeParamsTest < StrategyTestCase
     assert_equal 'touch', strategy.authorize_params[:display]
   end
 
-  test 'includes state parameter from request when present' do
-    @request.stubs(:params).returns({ 'state' => 'some_state' })
-    assert strategy.authorize_params.is_a?(Hash)
-    assert_equal 'some_state', strategy.authorize_params[:state]
-  end
-
   test 'overrides default scope with parameter passed from request' do
     @request.stubs(:params).returns({ 'scope' => 'email' })
     assert strategy.authorize_params.is_a?(Hash)

programming_language: Ruby