Recently I have been working on a site for a client who wanted every security item to be locked down as tightly as possible. And so I modified the script based on the Umbraco security best practices, I thought I'd share it with everyone, if I have missed anything, or if anyone has any suggestions on how to improve this, please let me know :)
Please refer to my previous post regarding the SetAcl command line application that you will need.
I suggest you save the following into a batch file called: umbPermSecure.bat
echo off
REM Script to setup the Security Permissions for an Umbraco site
REM This script will give your machine Network Service the minimum rights required
REM for Umbraco to work
REM I suggest you update this script to also remove any users who do not need
REM access to the web folders
REM **** Pre-requisites ****
REM You will need to download -> http://setacl.sourceforge.net/
REM It is assumed that you have stored SetACL in a directory called, C:\SetACL if
REM not, you will need to modify the script.
REM **** Usage ****
REM You need to pass in the path for the root of your Umbraco directory
REM E.g. umbPermSecure.bat C:\inetpub\umbracoroot
@echo umbPermSecure.bat - Script to set Umbraco File and Directory Permissions
@echo based on the Umbraco Security Best Practices Document (13th March 2009)
@echo Published by Chris Houston - 19th October 2009
@echo http://blog.vizioz.com
@echo Adding READ only access
SetACL.exe -on "%1" -ot file -actn ace -ace "n:%computername%\NETWORK SERVICE;p:read"
-actn clear -clr "dacl,sacl" -log "c:\setacl\log.txt"
SetACL.exe -on "%1\web.config" -ot file -actn ace -ace "n:%computername%\NETWORK SERVICE;p:read"
-actn clear -clr "dacl,sacl" -log "c:\setacl\log.txt"
SetACL.exe -on "%1\bin" -ot file -actn ace -ace "n:%computername%\NETWORK SERVICE;p:read"
-actn clear -clr "dacl,sacl" -log "c:\setacl\log.txt"
SetACL.exe -on "%1\umbraco" -ot file -actn ace -ace "n:%computername%\NETWORK SERVICE;p:read"
-actn clear -clr "dacl,sacl" -log "c:\setacl\log.txt"
@echo Adding READ and EXECUTE access
SetACL.exe -on "%1\app_code" -ot file -actn ace -ace "n:%computername%\NETWORK SERVICE;p:read_ex"
-actn clear -clr "dacl,sacl" -log "c:\setacl\log.txt"
SetACL.exe -on "%1\usercontrols" -ot file -actn ace -ace "n:%computername%\NETWORK SERVICE;p:read_ex"
-actn clear -clr "dacl,sacl" -log "c:\setacl\log.txt"
@echo Adding READ, WRITE and MODIFY access
SetACL.exe -on "%1\config" -ot file -actn ace -ace "n:%computername%\NETWORK SERVICE;p:read"
-ace "n:%computername%\NETWORK SERVICE;p:change" -actn clear -clr "dacl,sacl" -log "c:\setacl\log.txt"
SetACL.exe -on "%1\css" -ot file -actn ace -ace "n:%computername%\NETWORK SERVICE;p:read"
-ace "n:%computername%\NETWORK SERVICE;p:change" -actn clear -clr "dacl,sacl" -log "c:\setacl\log.txt"
SetACL.exe -on "%1\data" -ot file -actn ace -ace "n:%computername%\NETWORK SERVICE;p:read"
-ace "n:%computername%\NETWORK SERVICE;p:change" -actn clear -clr "dacl,sacl" -log "c:\setacl\log.txt"
SetACL.exe -on "%1\masterpages" -ot file -actn ace -ace "n:%computername%\NETWORK SERVICE;p:read"
-ace "n:%computername%\NETWORK SERVICE;p:change" -actn clear -clr "dacl,sacl" -log "c:\setacl\log.txt"
SetACL.exe -on "%1\media" -ot file -actn ace -ace "n:%computername%\NETWORK SERVICE;p:read"
-ace "n:%computername%\NETWORK SERVICE;p:change" -actn clear -clr "dacl,sacl" -log "c:\setacl\log.txt"
SetACL.exe -on "%1\python" -ot file -actn ace -ace "n:%computername%\NETWORK SERVICE;p:read"
-ace "n:%computername%\NETWORK SERVICE;p:change" -actn clear -clr "dacl,sacl" -log "c:\setacl\log.txt"
SetACL.exe -on "%1\scripts" -ot file -actn ace -ace "n:%computername%\NETWORK SERVICE;p:read"
-ace "n:%computername%\NETWORK SERVICE;p:change" -actn clear -clr "dacl,sacl" -log "c:\setacl\log.txt"
SetACL.exe -on "%1\xslt" -ot file -actn ace -ace "n:%computername%\NETWORK SERVICE;p:read"
-ace "n:%computername%\NETWORK SERVICE;p:change" -actn clear -clr "dacl,sacl" -log "c:\setacl\log.txt"
Cool, thanks for sharing this Chris. Will come in handy for sure. One thing, if I can weigh in... NETWORK SERVICE is a fiarly scary user account in a production environment. It gives permission to imperonate a client after authentication among other things. I tend to stick with the ASP.NET user account for these priveleges. It may not be as big a deal as I think, but just wanted to point it out.
ReplyDeleteThanks again!
Hi Nik,
ReplyDeleteI am happy to be corrected if someone can suggest an improvement :)
I was thinking of also adding to this script a line that deletes the Install directory, as I think that is quite often forgotten and left.
I hope others who know more about security than me can shed some more light on whether this is good or bad practice so that I can update the script accordingly :)
Nice, Chris!
ReplyDeleteBy default, IIS5 (winXP) uses the ASPNET user for websites and IIS6 and IIS7 use NETWORK SERVICE as the default application pool owner.
It would be great if you could determine the app pool owner at the start of your script, or at least allow an optional parameter if someone like Nik has a different user set for the application pool owner.
cheers,
doug.
Hi Chris,
ReplyDeleteThanks for this. What do you recommend for securing the Umbraco administration interface on a single instance of IIS, so that it's not publicly available? Adding in IP Restrictions is ok, but ideally the ./umbraco/ admin site would only be accessible from the LAN where it's hosted. Is the only way in using two instances of Umbraco, one on a LAN-only interface, disabling ./umbraco/ (or removing ./umbraco_client ?) on the internet facing server?
Hi Andrew,
ReplyDeleteWhy would you want to do this? This means that your users cannot work from home, unless they always have VPN access which I would think makes it quite restrictive and I think one thing most clients like is the flexibility it gives them to edit the content wherever they are.
That being said, one way you could do this is to setup two websites pointing to the same folder / database. One on the internal IP address and the other external.
On the external one you could then block access to the admin section within IIS.
You would probably have to add something to the Publish event so that when you do a publish on the private site it then updates the cache on the public site.
My preference thou, would be to rename the directory to make it very unlikely for people to find accidentally, add an SSL certificate so that the data transferred is secure and allow it to still be accessed from anywhere.
Thanks for the snippet.
ReplyDeleteHowever I Got an error saying "The SID for a trustee could not be found", so I googled around and found out that it could be due to the installed windows environment.
Once I removed the "%computername%\" part from each setacl.exe call, it worked perfectly.
More info could be found here: http://helgeklein.com/setacl/documentation/command-line-version-setacl-exe/#trustee-1
Many thanks!