Six ways to secure your Umbraco back office
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="{HTTP_HOST}" negate="true" pattern="^subdomain\.domain\.net$" /> <add input="{HTTP_HOST}" negate="true" pattern="^another-domain\.com$" /> <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="{HTTP_HOST}" negate="true" pattern="^subdomain\.azurewebsites\.net$" /> <add input="{HTTP_HOST}" negate="true" pattern="^another-domain\.com$" /> <add input="{URL}" pattern="/Umbraco/surface/*" 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: