Friday, August 20, 2010

How to secure a web folder in IIS 7 by denying IP addresses other than your own

I spent 3 days trying to think of a way to secure a web folder which contained sensitive files. I wanted public users to be able to upload files to that folder but i didn't want them to be able to view it. In other words, Write but no Read. The only way to view the file is within my application which the user needs to be authenticated using Forms Authentication (SqlMembershipProvider). Now there were different approaches on how to secure web folders. The 1st one is using ASP.NET authorization which looks like this on a web.config:

<location path="uploads">
     <system.web>
          <authorization>
               <allow users="myself"/>
               <deny users="*"></deny>
         </authorization>
     </system.web>
</location>

Sadly, this didn't work. Anyone could just type in the full url path to the file and view it without being authenticated.

The 2nd one is through IIS 7 URL Authorization which looks like this on a web.config:

<location path="uploads">
       <system.webServer>
             <security>
                  <authorization>
                          <add accessType="Allow" users="myself" />
                          <remove users="*" roles="" verbs="" />
                  </authorization>
             </security>
       </system.webServer>
</location>

Excitingly, this blocked all requests to the files I wanted to hide. Sadly, even my application wasn't able to access the files. IIS 7 URL Authorization doesn't care about any ASP.NET authenticated user.

The 3rd option was the one that worked for me. Using IIS 7 Url Rewrite, I created a rule denying requests from IP addresses that don't match my server's IP address. Just put a web.config file into the folder you want to secure and put the entry below. Just replace the IP address below with your server's IP.

<system.webServer>
      <rewrite>
            <rules>
                 <rule name="RequestBlockingRule1" patternSyntax="Wildcard"                   stopProcessing="true">
                        <match url="*" />
                                <conditions>
                                        <add input="{REMOTE_ADDR}" pattern="77.11.36.12" negate="true" />
                                </conditions>
                                <action type="CustomResponse" statusCode="403" statusReason="Forbidden: Access is denied." statusDescription="You do not have permission to view this directory or page using the credentials that you supplied." />
                  </rule>
           </rules>
      </rewrite>
</system.webServer>

Hope this helps someone out there.

No comments:

Post a Comment