Keeping a public website secure from cyber attacks is increasingly difficult. If you are running your site with Umbraco, there are a number of practices and hardening steps to take. I am keeping this post as a running checklist so that it can be used to supplement an Umbraco security audit checklist, with each section digging into Umbraco security best practices as well as web security practices.
Serving a site with HTTPS is a given these days. There was a time when SSL encryption was a performance concern, but with SSL offloading and modern encryption algorithms, there is no excuse to serve site traffic via HTTP.
To serve a site via HTTPS you'll need an SSL Certificate. Be aware that not all certificates are made equal. Your certificate should use at least 2048 bit encryption to keep the hashed key secure. The Qualys SSL checker is a good way to verify the quality of your certificate. I run this checker against various sites to measure certificate security. Make sure your cert complies with the following:
This is an example of the Qualys report results using the TangentTechnologies.ca site.
Ensure that your web.config includes a URLRewrite rule to redirect HTTP traffic to HTTPS.
Ensure that users passwords are complex and are changed frequently. User account and password policies should be configured to ensure the following:
Password rules can be configured using the UsersMembershipProvider. The UmbracoMembershipProvider is used for accounts that your site is hosting, not for CMS accounts.
<!-- Membership Provider --> <membership defaultProvider="UmbracoMembershipProvider" userIsOnlineTimeWindow="15"> <providers> <clear /> <add name="UmbracoMembershipProvider" type="Umbraco.Web.Security.Providers.MembersMembershipProvider, Umbraco" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="10" useLegacyEncoding="false" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="false" defaultMemberTypeAlias="Member" passwordFormat="Hashed" allowManuallyChangingPassword="false" /> <add name="UsersMembershipProvider" type="Umbraco.Web.Security.Providers.UsersMembershipProvider, Umbraco" minRequiredNonalphanumericCharacters="2" minRequiredPasswordLength="14"/> </providers> </membership>
In the above code example I have added the minRequiredPasswordLength setting and set it to 10. I have also added the minRequiredNonalphanumbericCharacters attribute which requires special characters and set it to 2.
NOTE: if you have existing accounts with passwords that do not meet stricter password requirements your users will not be able to change their passwords as the password policy will be applied to the existing password.
Better yet, integrate Umbraco authentication with Azure AD or third party OAUTH2. This opens up more powerful account policies and multifactor authentication. Your users will also appreciate not having another account to manage.
While the focus of this post is on Umbraco security, I think it's important to mention infrastructure security. The closer you can get to a PaaS setup, the better. Having to patch OS versions and harden a Windows/IIS install can be a time consuming and error prone.
If you are running Umbraco on VMs, I recommend a load balanced pair of Content Delivery web servers connected to a common content Database. The following is a standard High Availability Umbraco Azure architecture with VNet isolation between the Content Delivery and Content Management.
Umbraco runs well in Web App Services with a Azure SQL PaaS database. There is an Azure Marketplace image that will provision this infrastructure configuration. PaaS has many security advantages.
With Azure PaaS you still have the ability to use Application Gateway to load balance and protect your Web Application Services, or Azure Front Door (See my post on how to set this up)
Once you have the site environment secured, it's time to look at Umbraco itself.
The key here is reducing the amount of information that can be deduced about your site technology. It should not be possible to identify your site as an Umbraco site, or as an ASP.net powered site either.
It is difficult to attack a site with no knowledge of the underlying technology running the site.
Don't allow your site to publicly expose the /umbraco path and load the backoffice login screen. This is a dead giveaway, and to make matters worse it allows attackers access to a login screen that they can run through a brute force account cracker.
The CMS backoffice (default path https://mysite.com/umbraco) should not be accessible from the public internet. I have described one approach to block access by IP address using IIS, but there other alternatives that may be useful depending on your Umbraco Infrastructure.
Umbraco recommends using the IISRewrite module and locking down the Umbraco backend with a IISRewrite.Config file. If you go with this approach, I recommend renaming the umbraco folder because an attempt to access that folder will return a "403 not authorized" error which still reveals the presence of that path.
Renaming the Umbraco folder is also a good idea. Security through obfuscation.
There are a few other folders that Umbraco and ASP.net add that may reveal the site technology. I owe credit to perplex for a lot of this list.
No Visual Studio project files (.csproj, .sln) or code files (.cs) should be deployed to you production site. Ensure that your deploy process is excluding these files
Set x-frame-options to "SAMEORIGIN". The "DENY" setting will break the Umbraco Back End.
<httpProtocol> <customHeaders> <add name="X-Frame-Options" value="SAMEORIGIN" />
Set httpOnlyCookies to true and requireSSL to true. This will only allow cookies to be transferred over HTTPS connections.
<httpCookies httpOnlyCookies="true" requireSSL="true"/>
The "Yellow Screen of Death" reveals that your site uses ASP.net. It is also a bad user experience. Make sure to implement a robust error handling strategy and to capture runtime exceptions as 500 errors.
Wordpress plugins as notorious for introducing security holes. Adding unverified code to a site comes with a high level of risk, no matter what platform. Keep plugins to a minimum.
Many plugins are open source, review the code before using a plugin and pay close attention to code that interacts with the user authentication and authorization code.
Umbraco is very easy to upgrade, expecially within major versions. It had never taken me more than a day to update a minor Umbraco version. Umbraco security vulnerabilities are listed on the Umbraco page of the CVE Vulnerabilties site and should be checked regularly. The following is an example of the information available on the CVE site.
There was once an analyser provided by perplex that you could supply with a domain and it would determine if a site is running Umbraco, but this has been removed.
Run OWasp ZAP against your site to check for common vulnerabilities. OWasp Zap is free a desktop client that can scan your site and provide a report on potential security issues ranked by severity.
Download ZAP to check your site. This tool is not specific to Umbraco, and can be used to penetration test any website. Note that Penetration Testing is much more than just running a tool against your site. There are companies that specialize in this type of testing and if you site requires advanced security to achieve regulatory compliance I highly recommend engaging a company that provides this service.