Earlier this year, the Checkmarx Security Research Team conducted an investigation of the new version of Drupal Core (Drupal 9) – a content management system (CMS) written in PHP – uncovering several interesting issues whose technical details are worth discussing openly. This article covers the technical facets of CVE-2020-13663 that were made public by Checkmarx in June 2020, but whose details were never discussed publicly, and serves as part 1 of breaking down the vulnerabilities identified during our Drupal research. The issues outlined below were resolved by the Drupal security team shortly after we reported them.
CVE-2020-13663 - OverviewDrupal Security Risk: Critical - https://www.drupal.org/sa-core-2020-004 Vulnerable versions:
- Drupal 7 – before 7.72
- Drupal 8.8 – before 8.8.8
- Drupal 8.9 – before 8.9.1
- Drupal 9 – before 9.0.1
CVE-2020-13663 - Reflected DOM XSS in Rejected Forms
Vulnerability Proof of Concept (PoC)The following code would recreate the issue on any vulnerable version of Drupal Core, so long as Basic Page functionality exists and URL rewrites are not altered. It will affect any user who is authenticated and has permissions to both add the page and use a Full HTML mode. Otherwise, values such as form “action” and form_id “value” may require alteration: An authenticated user with HTML content creation permissions will observe the result of script execution: While Cross-site Request Forgery (CSRF) mitigation prevents the form from going through and adding a new page, Drupal attempts to fail gracefully so that content that has been submitted is not lost because a security mechanism rejected it. A message is shown to indicate the form is rejected, but the user may still retrieve its contents from the form: The posted content is reflected in the page to allow users to copy it to a valid form in a CKEditor view. The CKEditor view, like a Microsoft Word document, contains live elements such as images, figures, and more. These live elements are rendered HTML elements, which, in theory, could contain malicious code. While CKEditor does generally account for this by offering some protection against this type of DOM XSS and specifically strips script tags, the way it is configured on Drupal allows bypassing that by planting the script tags inside an iframe.
- form_id parameter: e.g. node_article_form, node_page_form, which are the default form types
- A parameter name to inject a value into: in both default cases here (“Article” and “Basic Page”), this is body[value], but generally, a CKEditor element can be derived from the field’s classes, e.g., text-formatted or field-type-text-with-summary to realize it is a component generated by CKEditor, and field-name-body to get the field’s name
- Forcing format mode to “Full HTML” for the payload to trigger, e.g., body[format]; otherwise, this will simply be the current value, which could be restricted and block out the payload
- Inject malicious code into webpages via Cross-Site Scripting to:
- Hijack user accounts
- Inject malicious web-content, such as malicious login or payment forms