On July 9th, the Umbraco 8.1.0 and 7.15.0 releases, and the provided manual security fix, proved to fix part of the security vulnerability, yet there was still a different attack vector present that was a bit harder to find. Today, we are releasing a fix for this.
If you have already implemented the manual fix provided in the Security Advisory from the 9th of July 2019, on sites running versions older than 7.15.0 or 8.1.0, then you still need to update the code, as listed below, to provide additional protection.
If you are uncertain about how to handle this advisory, reach out to your technical contact for your Umbraco site and provide them with a link to this blog post and they will be able to take the necessary precautions.
What is affected?
Sites/projects running the following versions are affected:
- 6.2.0-6.2.6 (any Umbraco version 6 site since 6.2.0)
- 7.0.0-7.15.0 (any Umbraco version 7 site since 7.0.0 and lower than 7.15.1)
- 8.0.0-8.1.0 (any Umbraco 8 site since 8.0.0 and lower than 8.1.1)
Any websites that are publicly available on the internet are impacted. Any sites that are not publicly available can still be impacted if there is a malicious actor within the network where the website is available.
This is classified as high severity.
Patches - how to fix it
This vulnerability is fixed in Umbraco 7.15.1 and 8.1.1. Both have been released today.
Umbraco Cloud sites currently running Umbraco version 8.1.0 or 7.15.0 will automatically get this security patch today and thus, do not have to take any action.
If your Umbraco Cloud site uses a version older than 7.15.0 or 8.1.0, you will need to take manual steps to secure your sites. Either you opt into the upgrade to 7.15.1 / 8.1.1 or you apply the workaround below.
If you can upgrade to Umbraco version 7.15.1 or 8.1.1, that would be the preferred way to fix this problem.
For anybody who can not upgrade or needs a quick fix, there's some code that can be added to App_Code or added to the custom code you put into your vulnerable sites. The fix is similar to what was published in our previous advisory but has been updated to reduce more attack vectors, so wether you’ve followed the previous advisory or not, make sure to update the code.
As a fix, the code below is available. This code prevents anyone (also your own existing code!) from creating members through the vulnerable controller UmbRegisterController. If you are currently using UmbRegisterController to create members, please read the detailed explanation in the next section to see if you need to take action to rewrite some of your code.
Additionally, logged in members can update their own member profile with a simple POST request to UmbProfileController, so if you really do not want members to be able to update their information, that bypass is also fixed in the code linked below.
There are two other publicly available controllers shipped with Umbraco that you may wish to disable. These controllers allow a member to log in to the website and display their login status. If you are not using members on your website you can also disable these controllers with the code provided below. These controllers are called UmbLogin and UmbLoginStatus and both of these controllers are now also protected in the same way as the UmbProfile and UmbRegister controllers are in 7.15.1 and 8.1.1.
Update 31st of July 2019:
In the code for the manual workaround that we posted in this Security Advisory on the 30th of July, we made a small copy/paste error. The last RouteTable was looking for a route called “umbraco-surface-Tags” but that should have been “umbraco-api-Tags”. This has now been corrected in the workaround code links provided below.
What is the impact of this error? The manual workaround posted on the 30th of July still completely protects you against the high-impact vulnerability concerning member registration thus, nobody would have been able to exploit that vulnerability. The code did, however, leave content Tags publicly available on your site, and if that is a concern for you, then you should update the workaround by replacing “umbraco-surface-Tags” with “umbraco-api-Tags”. Otherwise, you don’t need to take any action.
If you have upgraded, or plan to upgrade, to either Umbraco version 7.15.1 or 8.1.1 you don’t have to take any action on this as this error only concerns the manual workaround.
For Umbraco 6 and Umbraco 7 sites, get the workaround code here.
For Umbraco 8 sites, get the code workaround here.
Versions 8.1.0 and 7.15.0 also removed a publicly available endpoint that could return a listing of content Tags in your website. We would like to take this opportunity to advise that if you use Tags in your content on your website and do not want to expose these publicly that you can use the same work around listed here for the TagsController if you are using versions lower than 8.1.0 or 7.15.0.
Some care must be taken when custom routes are added to a website, most notably the default route such as:
Since this route will match all controllers, it means that these controllers could still be routed to by another URL. The workaround only removes the default (automatically added) MVC routes for the surface controllers so if you are also using a default route like above then you will probably want to add a route constraint so that these controllers are not matched. For example, changing the default route to have a route constraint to not match any controller names suffixed with “UmbProfile”, “UmbRegister”, “UmbLogin”, “UmbLoginStatus” or “Tags”
An example of the route constraints is available on here so that you can easily copy & paste them.
In version 6.2.0 of Umbraco we introduced some handy snippets for people to easily create a macro to be able to register new members in Umbraco. Conveniently you would not need to write your own code for this, just add a macro from a snippet and you're good to go.
This publicly exposed a controller (UmbRegisterController) with a predictable route. This allows anyone who knows this route to send a POST request to that route and register a member in your website.
Registering a member is not necessarily a big problem, unless you are (for example) running an intranet or put any other non-public data behind a login on your website. Suddenly people who have not been invited will be able to create an account.
Typically when exposing private data or privileged functionality to registered members of your site, you would require members to be in a certain Role (this is called a Member Group in Umbraco). The exposed UmbRegisterController does not provide a method to assign members to a Role / Member Group.
Please make sure that any data / functionality you do not want to be publicly available is properly secured by requiring members to be in a certain Role / Member Group.
Additionally, snippets exist for:
- Updating a member’s profile, this is also vulnerable but the vulnerability is a lot less severe, an attacker would have to specifically target a currently logged in member on an Umbraco site
- Logging in a member was possible using the same technique as registering a member, so if an attacker used the previous attack to register a new member, and the account was still active, they could still have access to the site
Finally, as explained above, it was possible for unauthenticated site visitors to get a list of all the tags used in the website, if that’s a concern for you then this has been fixed since 7.15.0 / 8.1.0.
The fix in Umbraco version 7.15.1 and 8.1.1 explained
For the previous fix for 7.15.0/8.1.0 we were alerted that the controller-specific anti-forgery token implemented was not sufficient because this fix only worked for controllers that were routed to by Umbraco's internal routing logic. It is possible to route directly to these controllers and bypass the internal routing logic which means bypassing the controller specific anti-forgery token check.
In the fix for 7.15.1 and 8.1.1 we now only allow routing to these controllers by Umbraco's internal routing logic. These controllers are no longer directly routable because there is a check to validate the internal routing token which can only exist and be valid if rendering a form for these controllers on your website using the BeginUmbracoForm razor helper.
We'd like to thank Ronald Barendse from Panorama Studios and Steven Harland from Intelligent Mobile for their additional research and responsible disclosure concerning this vulnerability.
For more information
If you have any questions or comments about this advisory, make sure to get in touch with us through our security email address as listed on https://umbraco.com/security.