A while back I was playing around with the OAuth2 spec and discovered a flaw in how Vimeo associates Facebook accounts. Their Facebook connect callback URL was vulnerable to a Cross Site Request Forgery, allowing an attacker to connect their Facebook account with a victim's Vimeo account.
If you try to connect a Facebook account to your Vimeo account, Vimeo sends you to the following URL:
Once you accept the authorization prompt, Facebook returns an HTTP 302, redirecting you back to Vimeo's
redirect_uri along with a
code that Vimeo uses to access your Facebook info and associate the accounts.
Along with the
code, Facebook sends back the
state value from the URL above so that Vimeo can verify that the callback request is authentic and originated from the same browser that started the flow.
Vimeo correctly set a
state parameter, but used code similar to the following to verify the state:
def callback if params[:state] == session[:state] # associate accounts else # error csrf detected! end end
But what is
session[:state] when the request is not authentic?
1) The attacker logs into their own Vimeo account and beings the flow to connect their Facebook account.
2) The attacker accepts all permissions, but uses a tool like NoRedirect to block their browser from making the final redirect back to Vimeo:
3) The attacker uses this URL, omitting the
state parameter as part of a CSRF attack on a page that the victim (who is currently logged into Vimeo) is likely to view.
<img src='https://vimeo.com/settings/apps?action=connect&service=facebook&code=<CODE>#_=_' />
4) The victim's Vimeo account is now associated with the attacker's Facebook account. The attacker can now use their Facebook to login to the victim's Vimeo account.
The callback must ensure that the
state query parameter matches the persisted
state token AND that both values are non-nil.
- 04 Feb 2015 - Reported the vulnerability to Vimeo
- 25 Feb 2015 - Vimeo marked the report as a 'duplicate'
- 25 Feb 2015 - Vimeo requests verification on the 'duplicate' report
- 26 Feb 2015 - Verified that Vimeo's fix corrected this issue, but the 'duplicate' bug remained vulnerable
- 06 Mar 2015 - The 'duplicate' report was independently disclosed publicly by Egor Homakov.
- 02 Apr 2015 - No updates from Vimeo on the 'duplicate' issue or acknowledgment that two reports were separate vulnerabilities