{"id":125,"date":"2017-02-21T17:09:07","date_gmt":"2017-02-21T06:09:07","guid":{"rendered":"https:\/\/www.aspireweb.com.au\/blog\/?p=125"},"modified":"2017-02-21T20:53:37","modified_gmt":"2017-02-21T09:53:37","slug":"php-file-permissions-on-windows-10-iis","status":"publish","type":"post","link":"https:\/\/aspireweb.com.au\/blog\/php-file-permissions-on-windows-10-iis\/","title":{"rendered":"Lock Down PHP File Permissions on Windows 7\/10 and IIS"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" class=\"alignright wp-image-134 size-medium\" src=\"https:\/\/www.aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/computer-1591018_1920-300x196.jpg\" width=\"300\" height=\"196\" srcset=\"https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/computer-1591018_1920-300x196.jpg 300w, https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/computer-1591018_1920-128x84.jpg 128w, https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/computer-1591018_1920.jpg 480w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><strong>How do I set up file permissions in Windows for PHP?<\/strong><\/p>\n<p>When using PHP permissions are\u00a0misunderstood and common response\u00a0is just giving too much access which is a security nightmare!<\/p>\n<p>This is extremely important when configuring IIS manually on a VPS or Dedicated server, you want each site isolated from each other. This protects your server and other websites if one site is hacked or compromised.<\/p>\n<p>If you&#8217;re just developing locally this isn&#8217;t too bad but it&#8217;s good practice to always configure it correctly, this will help find errors you may encounter in production but also that we should always be thinking about security.<\/p>\n<p>Any reputable Windows web host would also be configuring their servers automatically using a control panel to configure secure permissions and website isolation so there is no need to worry about this if your with a shared website host. Most control panels will allow you to change if write permissions are enabled or not, this is a common fix for shared hosts and write permission issues.<\/p>\n<p>Web development has changed a lot over the years and security is now a big focus point for web developers so while some would like to leave the IIS &amp; Windows configuration to their server admins it&#8217;s good to understand and take responsibility.<\/p>\n<p>It&#8217;s not hard to configure and after you&#8217;ve done it you&#8217;ll feel great knowing that you&#8217;re website is substantially more secure so let&#8217;s go.<\/p>\n<p><!--more--><\/p>\n<p>Before we start, this post\u00a0will assume you already have IIS with relevant features and\u00a0PHP installed and working.<\/p>\n<p>In the image below shows a basic example of how the security model works.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-130\" src=\"https:\/\/www.aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/iis-security-context.png\" alt=\"\" width=\"718\" height=\"536\" srcset=\"https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/iis-security-context.png 718w, https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/iis-security-context-300x224.png 300w, https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/iis-security-context-128x96.png 128w\" sizes=\"auto, (max-width: 718px) 100vw, 718px\" \/><\/p>\n<p>Each website runs as a different &#8220;user&#8221; and that user has access to their website folder. They also both have access to system and PHP files else that user couldn&#8217;t execute PHP to run.<br \/>\nJust a quick note before continuing, when running on Windows ignore anything that talks about the Linux security like the 770 or 665 flags, these aren&#8217;t compatible with Windows.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>So where does this website user come from?<\/strong><\/p>\n<p>Either you can make a new system user for the purpose of the website or if you are running IIS 7 or higher you can run as a hidden IIS worker user. It&#8217;s hidden because you cannot just search for this user, you need to manually type in the name. In this we will be adding the IIS worker user to streamline the process.<\/p>\n<p>&nbsp;<\/p>\n<p>First we need to create a new website with it&#8217;s own application pool.<\/p>\n<div id=\"attachment_126\" style=\"width: 598px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-126\" class=\"wp-image-126 size-full\" src=\"https:\/\/www.aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_040347_PM.jpg\" width=\"588\" height=\"571\" srcset=\"https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_040347_PM.jpg 588w, https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_040347_PM-300x291.jpg 300w, https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_040347_PM-128x124.jpg 128w\" sizes=\"auto, (max-width: 588px) 100vw, 588px\" \/><p id=\"caption-attachment-126\" class=\"wp-caption-text\">Fig A<\/p><\/div>\n<p>If we check this new application pool in the advanced settings we will see that it&#8217;s running as the &#8220;ApplicationPoolIdentity&#8221;.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"wp-image-127 size-full\" src=\"https:\/\/www.aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_040546_PM.jpg\" width=\"432\" height=\"544\" srcset=\"https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_040546_PM.jpg 432w, https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_040546_PM-238x300.jpg 238w, https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_040546_PM-102x128.jpg 102w\" sizes=\"auto, (max-width: 432px) 100vw, 432px\" \/><\/p>\n<p>Fig B<\/p>\n<p><strong>Lets go add some permissions<\/strong><\/p>\n<p>First we need to change\u00a0the permissions to our new website folder.<\/p>\n<p>Navigate to the folder and open the properties page, go to the security tab and then Advanced.<br \/>\nClick &#8220;Disable inheritance&#8221; and choose &#8220;Convert inherited permissions into explicit permissions on this object&#8221;.<\/p>\n<div id=\"attachment_128\" style=\"width: 1144px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-128\" class=\"wp-image-128 size-full\" src=\"https:\/\/www.aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_041219_PM.jpg\" width=\"1134\" height=\"517\" srcset=\"https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_041219_PM.jpg 1134w, https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_041219_PM-300x137.jpg 300w, https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_041219_PM-768x350.jpg 768w, https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_041219_PM-1024x467.jpg 1024w, https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_041219_PM-128x58.jpg 128w\" sizes=\"auto, (max-width: 1134px) 100vw, 1134px\" \/><p id=\"caption-attachment-128\" class=\"wp-caption-text\">Fig C<\/p><\/div>\n<p>Now that this folder has it&#8217;s own permissions (no longer inherited) we need to remove the users group and the IIS_USRS if it exists (Depends where your folder is). There may be other permissions as well but you really should only have System, Administrators, Creator Owner, your login name (not always) and trusted installer left on the folder.<\/p>\n<p>We now need to add the IIS Application Pool to the folder, so click &#8220;Add&#8221; and on the next form click &#8220;Select a principal&#8221;, on this form type in &#8220;IIS AppPool\\mynewsite&#8221; replacing &#8220;mynewsite&#8221; with your site application pool name from Fig A. Click &#8220;OK&#8221; and if you&#8217;ve done it right it will fill in the Principal as the Application pool name as per below (1, Fig D).<\/p>\n<div id=\"attachment_129\" style=\"width: 520px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-129\" class=\"wp-image-129 size-full\" src=\"https:\/\/www.aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_042220_PM.jpg\" width=\"510\" height=\"462\" srcset=\"https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_042220_PM.jpg 510w, https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_042220_PM-300x272.jpg 300w, https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_042220_PM-128x116.jpg 128w\" sizes=\"auto, (max-width: 510px) 100vw, 510px\" \/><p id=\"caption-attachment-129\" class=\"wp-caption-text\">Fig D<\/p><\/div>\n<p>For most sites you will want write and modify permissions so go ahead and tick modify (it will tick write automatically) and then &#8220;OK&#8221; this form. A couple more &#8220;OK&#8221;&#8216;s and you&#8217;ll have saved the new permissions!<\/p>\n<p>Well Done, if all goes well you should now be able to browse to your site and confirm it&#8217;s working.<\/p>\n<p>I used a simple <a href=\"https:\/\/www.aspireweb.com.au\/blog\/how-do-i-create-a-phpinfo-page\/\">PHPinfo file<\/a> to test ours.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>HELP It Didn&#8217;t Work!<\/strong><\/p>\n<p>There are range\u00a0of reasons why this wouldn&#8217;t work.<\/p>\n<p>Here are a few things to try:<\/p>\n<ul>\n<li>If your getting a 401.3 Error we need to check that the website is indeed using the Application Pool identity.Go to IIS and select your website, double click\u00a0&#8220;Authentication&#8221; to open this feature. Right click &#8220;Anonymous Authentication&#8221; and select edit. Make sure that &#8220;Application pool identity&#8221; is selected and click &#8220;OK&#8221;.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-131\" src=\"https:\/\/www.aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_044503_PM.jpg\" alt=\"\" width=\"504\" height=\"408\" srcset=\"https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_044503_PM.jpg 504w, https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_044503_PM-300x243.jpg 300w, https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_044503_PM-128x104.jpg 128w\" sizes=\"auto, (max-width: 504px) 100vw, 504px\" \/><br \/>\nTry your website again and see if this fixed the issue.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li>Does the application pool have access to PHP?This error will generally show as a 500 Internal Server Error. In the details section it will show as a FastCgiModule with the name of the handler listed.<br \/>\nTo verify if this is the problem, add the &#8220;IIS AppPool\\mynewsite&#8221; user to your PHP folder.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-133\" src=\"https:\/\/www.aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_045456_PM.jpg\" alt=\"\" width=\"754\" height=\"758\" srcset=\"https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_045456_PM.jpg 754w, https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_045456_PM-150x150.jpg 150w, https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_045456_PM-298x300.jpg 298w, https:\/\/aspireweb.com.au\/blog\/wp-content\/uploads\/2017\/02\/Screenshot_022117_045456_PM-128x128.jpg 128w\" sizes=\"auto, (max-width: 754px) 100vw, 754px\" \/><br \/>\nAfter doing this restart IIS and try running your site again. (Sometimes you need to restart IIS so always do this else you may miss when you&#8217;ve fixed the issue)<\/li>\n<li>If this fails, we really need to diagnose where the issue is before trying anything else.The best way to diagnose this is using <a href=\"https:\/\/technet.microsoft.com\/en-us\/sysinternals\/processmonitor.aspx\">Process Monitor\u00a0from Sysinternals<\/a>, how to use this tool is a out of scope for this post but as an overview you run it while trying to go to your website. We then look for any access denied&#8217;s for file operations, then we can find out what user is trying to access which file and fix the permissions on that.Let us\u00a0know if diagnosing this way would be interesting for a blog post as it&#8217;s a tool we&#8217;ve used extensively when diagnosing hard to fix issues.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>Now this is a very basic overview of how to configure a single\u00a0website with basic file security in mind, if this were a VPS or Dedicated server care should be taken to lock down the whole machine permissions wise even if it&#8217;s only for internal websites.<\/p>\n<p>&nbsp;<\/p>\n<p>Aspire Web offers consulting so if you need a hand fixing or deploying a Windows server just contact us and we&#8217;ll see if we can help.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How do I set up file permissions in Windows for PHP? When using PHP permissions are\u00a0misunderstood and common response\u00a0is just giving too much access which is a security nightmare! This is extremely important when configuring IIS manually on a VPS or Dedicated server, you want each site isolated from each other. This protects your server [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,8,7],"tags":[],"class_list":["post-125","post","type-post","status-publish","format-standard","hentry","category-iis","category-php","category-security"],"_links":{"self":[{"href":"https:\/\/aspireweb.com.au\/blog\/wp-json\/wp\/v2\/posts\/125","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/aspireweb.com.au\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/aspireweb.com.au\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/aspireweb.com.au\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/aspireweb.com.au\/blog\/wp-json\/wp\/v2\/comments?post=125"}],"version-history":[{"count":8,"href":"https:\/\/aspireweb.com.au\/blog\/wp-json\/wp\/v2\/posts\/125\/revisions"}],"predecessor-version":[{"id":142,"href":"https:\/\/aspireweb.com.au\/blog\/wp-json\/wp\/v2\/posts\/125\/revisions\/142"}],"wp:attachment":[{"href":"https:\/\/aspireweb.com.au\/blog\/wp-json\/wp\/v2\/media?parent=125"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/aspireweb.com.au\/blog\/wp-json\/wp\/v2\/categories?post=125"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/aspireweb.com.au\/blog\/wp-json\/wp\/v2\/tags?post=125"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}