The aim of this post is to provide you with additional layers to the security of your Umbraco back office login page. By adding more layers of security you make it harder for someone with malicious intent to gain access to your Umbraco back office. Here are six ways to prevent that, starting from the fairly obvious to more technical.
1. Use a secure password or password manager
This is a very obvious one, avoid using common phrases or words for your password such as the famous "password1234" or "keepout", "qwerty" etc. Some seem like a clever idea and easy to remember but is probably already in a big guess list of common passwords that a password cracker would use. Ideally your password should be a random set of characters such as: 3NUg%3SW!zn756D or C^gh53M9gkGgkWx. Ideally everything you sign into should have a random password like this.
Check out, haveibeenpwned.com you simply enter your email address and they will provide you a list of sites that suffered database leaks containing the email specified. If any of your other online accounts share the same password as the sites you used in the list, change it ASAP!
But how can you remember and manage all these passwords? By using a password manager such as Lastpass or Dashlane, there are plenty more managers out there if you want something different. Such as Keepass a password manager that isn't an online service but an open source application that you install.
2. Don't use an email address or "admin" as your username for the admin account
Try to avoid using your personal email, “admin” or “[email protected]” as the username for your admin account. Using something a bit more obscure will make it harder for someone to login as they now have to guess both your username and password.
3. IP Restrict your back office via a rewrite rule (technical)
Perhaps you have a static IP address? Maybe at your office or on your own personal or work VPN (Virtual Private Network). You can restrict access to the back office using a rewrite rule in the web config. Like so:
<rule name="RestrictBackOffice" enabled="true" patternSyntax="Wildcard" stopProcessing="true">
<match url="*" />
<conditions>
<add input="{URL}" pattern="/Umbraco/*" />
<add input="{URL}" pattern="/Umbraco/surface/*" negate="true" />
<add input="{REMOTE_ADDR}" pattern="Your-IP" negate="true"/>
<add input="{REMOTE_ADDR}" pattern="Another-IP" negate="true"/>
<add input="{REMOTE_ADDR}" pattern="127.0.0.1" negate="true"/>
<add input="{HTTP_X_FORWARDED_FOR}" pattern="Your-IP" negate="true"/>
<add input="{HTTP_X_FORWARDED_FOR}" pattern="Another-IP" negate="true"/>
<add input="{HTTP_X_FORWARDED_FOR}" pattern="127.0.0.1" negate="true"/>
</conditions>
<action type="CustomResponse" statusCode="404" statusReason="File or directory not found." statusDescription="The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable." />
</rule>
Fill out Your-IP and/or Another-IP with your static IP address. Do not remove the condition with the IP 127.0.0.1! Specifying the input {Remote_ADDR} and {HTTP_X_FORWARDED_FOR} allows the rule to look at the IP address in the request.
This rule will look at the whole of the url in the request and look for anything going to /umbraco/*. It then checks if the request is coming from the specified IP's in the rule, 127.0.0.1 being the site making requests to itself. We then return a 404 status code when the request fails our conditions.
We additionally allow any requests to the Umbraco/surface controller, you can read more about the surface controller here. If your website has its own Umbraco API controllers you will need to permit them the same way we permit the surface controller.
Avoid using commercial VPN's for you static IP address as the IP address is shared with others.
4. Access your back office via an unknown url/domain (technical)
Perhaps you don’t have a safe static IP address to use (or you do, feel free to merge tips 3 and 4 together), you could restrict the back office to only open on a different url instead. If you have a spare domain lying around use that to access your back office, however I would avoid setting up a sub-domain as these can be queried externally for example here are some the sub-domains I found for Facebook:
Point is avoid doing this for a sub-domain on your main umbraco site domain.
If you are hosting your site on an azure web app, that will already have its own url assigned to it. It will usually have the format webapp-name.azurewebsites.net. This also can be queried with a public DNS checker site if your main site url is using a CNAME record to your azure web app.
However if you use Cloudflare on your website, they obscure this by hiding where the URL is pointing too. Regardless, even if someone does figure out your azure website url this is still another hurdle that someone would have to overcome. Just to view the Umbraco login page!
Below is the same IP restriction rewrite rule and the URL/Domain restriction together:
<rule name="RestrictBackOffice" enabled="true" patternSyntax="Wildcard" stopProcessing="true">
<match url="*" />
<conditions>
<add input="{URL}" pattern="/Umbraco/*" />
<add input="{URL}" pattern="/Umbraco/surface/*" negate="true" />
<add input="{REMOTE_ADDR}" pattern="Your-IP" negate="true"/>
<add input="{REMOTE_ADDR}" pattern="Another-IP" negate="true"/>
<add input="{REMOTE_ADDR}" pattern="127.0.0.1" negate="true"/>
<add input="{HTTP_X_FORWARDED_FOR}" pattern="Your-IP" negate="true"/>
<add input="{HTTP_X_FORWARDED_FOR}" pattern="Another-IP" negate="true"/>
<add input="{HTTP_X_FORWARDED_FOR}" pattern="127.0.0.1" negate="true"/>
</conditions>
<action type="CustomResponse" statusCode="404" statusReason="File or directory not found." statusDescription="The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable." />
</rule>
By using {HTTP_HOST} input and setting negate to true we can say if the request comes via a specific domain let it through.
Example without the IP restriction in play:
<rule name="RestrictBackOffice" enabled="true" patternSyntax="Wildcard" stopProcessing="true">
<match url="*" />
<conditions>
<add input="{URL}" pattern="/Umbraco/*" />
<add input="{URL}" pattern="/Umbraco/surface/*" negate="true" />
<add input="{REMOTE_ADDR}" pattern="Your-IP" negate="true"/>
<add input="{REMOTE_ADDR}" pattern="Another-IP" negate="true"/>
<add input="{REMOTE_ADDR}" pattern="127.0.0.1" negate="true"/>
<add input="{HTTP_X_FORWARDED_FOR}" pattern="Your-IP" negate="true"/>
<add input="{HTTP_X_FORWARDED_FOR}" pattern="Another-IP" negate="true"/>
<add input="{HTTP_X_FORWARDED_FOR}" pattern="127.0.0.1" negate="true"/>
</conditions>
<action type="CustomResponse" statusCode="404" statusReason="File or directory not found." statusDescription="The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable." />
</rule>
Here is a diagram outlining how this would look with Cloudflare:
5. Don’t access the back office over an insecure URL using Cloudflare SSL
If you are taking advantage of Cloudflare’s free SSL and don't have an SSL binding setup on the server. I would avoid accessing the back office over your main domain as the SSL certificate only protects the connection between you and Cloudflare. There is no guarantee that someone is listening to the unencrypted traffic between Cloudflare and your web server hosting your site. If you are using an Azure web app or VPS, accessing the back office via the azurewebsites.net domain or a domain pointing directly at the VPS, with an SSL binding, would be more secure as you are directly connected to your site as mentioned previously with an SSL certificate on the web server.
You can obtain a free SSL certificate with letsencrypt if you want to avoid paying for SSL or use your azure web app azurewbesites.net url.
6. Use Azure Active Directory to log into your back office
If you already use Azure AD for your organization you can configure Umbraco to use it too. This puts the authentication responsibility on Microsoft instead and leaves Umbraco to focus on delivering your content. With Azure AD you can enforce MFA (Multi Factor Authentication) through Azure adding another additional layer of security. See this article from Shannon Deminick to set it up: https://shazwazza.com/post/configuring-azure-active-directory-login-with-umbraco/.
Thanks for making it down here!
I hope you found this post useful and I hope it provided you with more tools to secure your Umbraco back office. Feel free to get in touch if it works out for you or if you notice something wrong in the post.