Software Description
Doorkeeper is a Ruby gem that makes it easy to introduce OAuth 2 provider functionality to a Rails or Grape application.
Depending on how a developer uses the gem, they may allow any registered user to create OAuth client applications in their software.
CVSSv3
Base Score: 7.6 (High)
Temporal Score: 6.8 (Medium)
Vector: AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:L/A:N/E:P/RL:O/RC:C
Attack Details
Stored XSS on the OAuth Client's name will cause users being prompted for consent via the "implicit" grant type to execute the XSS payload.
The XSS attack could gain access to the user's active session, resulting in account compromise.
Any user is susceptible if they click the authorization link for the malicious OAuth client. Because of how the links work, a user cannot tell if a link is malicious or not without first visiting the page with the XSS payload.
The requirement for this attack to be dangerous in the wild is the software using Doorkeeper must allow regular users to create or edit OAuth client applications.
If 3rd parties are allowed to create OAuth clients in the app using Doorkeeper, upgrade to the patched versions immediately.
Additionally there is stored XSS in the native_redirect_uri
form element.
DWF has assigned CVE-2018-1000088.
Proof of Concept
See Doorkeeper issue #970:
- Log in as a user capable of creating OAuth client applications
- Create an OAuth client application
- Set the Client Name to
<script>alert('XSS')</script>
- Trick other users to click your implicit authorization link
Timeline
- Discovered by Gauthier Monserand May 25, 2017
- Fix prepared by Gauthier Monserand May 25, 2017
- Maintainer released patched version May 26, 2017
- CVE requested February 17, 2018
- CVE assigned February 20, 2018
- This post is published February 21, 2018
Affected Versions
v2.1.0 – v4.2.5
Fix
Not Using Custom Views
If the software using Doorkeeper did not generate custom views, simply upgrade to v4.2.6 or greater.
Using Custom Views
Any software using Doorkeeper with custom views must manually escape the fields:
In app/views/doorkeeper/authorizations/new.html.erb
:
Look for the raw field for client_name
and ensure no explicit HTML exists in the value. Use Rails' safe helpers if HTML is required (such as content_tag
). e.g. this diff
- <%= raw t('.prompt', client_name: "<strong class=\"text-info\">#{ @pre_auth.client.name }</strong>") %>
+ <%= raw t('.prompt', client_name: content_tag(:strong, class: 'text-info') { @pre_auth.client.name }) %>
In app/views/doorkeeper/applications/_form.html.erb
:
Look for the raw field for native_redirect_uri
and ensure no explicit HTML exists in the value. Use Rails' safe helpers if HTML is required (such as content_tag
). e.g. this diff
- <%= raw t('doorkeeper.applications.help.native_redirect_uri', native_redirect_uri: "{gfm-js-extract-pre-1}") %>
+ <%= raw t('doorkeeper.applications.help.native_redirect_uri', native_redirect_uri: content_tag(:code) { Doorkeeper.configuration.native_redirect_uri }) %>
Credit & References
Discovered and fixed by Gauthier Monserand: