<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Chad Scharf&#039;s Weblog &#187; security</title>
	<atom:link href="http://www.chadscharf.com/index.php/tags/security/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.chadscharf.com</link>
	<description>It&#039;s always time to upgrade!</description>
	<lastBuildDate>Fri, 28 Oct 2011 22:14:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Protecting PDF files in IIS 6 using Forms Authentication</title>
		<link>http://www.chadscharf.com/index.php/2008/04/protecting-pdf-files-in-iis-6-using-forms-authentication/</link>
		<comments>http://www.chadscharf.com/index.php/2008/04/protecting-pdf-files-in-iis-6-using-forms-authentication/#comments</comments>
		<pubDate>Fri, 04 Apr 2008 03:32:00 +0000</pubDate>
		<dc:creator>Chad</dc:creator>
				<category><![CDATA[ASP.NET Development]]></category>
		<category><![CDATA[IIS]]></category>
		<category><![CDATA[ihttphandler]]></category>
		<category><![CDATA[iis 6]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://chadscharf.com/post.aspx?id=cb52d8b4-d442-418d-a5d3-d94c4ece3c86</guid>
		<description><![CDATA[Problem We have a very simple ASP.NET web site that uses the built in Forms Authentication provider out of the box for users, roles and security. Our internal business customers have hundreds of PDF documents that should only be accessible for specific users or roles within the company. A majority of users that need access [...]<p><a href="http://www.chadscharf.com/index.php/2008/04/protecting-pdf-files-in-iis-6-using-forms-authentication/">Protecting PDF files in IIS 6 using Forms Authentication</a> is a post from: <a href="http://www.chadscharf.com">Chad Scharf&#039;s Weblog</a>. For software consulting services please visit <a href="http://www.scharfholdings.com">Scharf Holdings, LLC</a></p>
]]></description>
			<content:encoded><![CDATA[<h2>Problem</h2>
<p>We have a very simple ASP.NET web site that uses the built in Forms Authentication provider out of the box for users, roles and security. Our internal business customers have hundreds of PDF documents that should only be accessible for specific users or roles within the company. A majority of users that need access to these files are outside the company firewall and do not have VPN access. The site must be hosted on Windows Server 2003 using IIS 6.</p>
<p>Although this problem could be solved in many ways, I wanted to make the site as dynamic as possible since our web master would need to make constant changes to files, structure, etc and we did not want a programmer having to make changes to specific code or a DBA maintaining a database of files, paths, etc. We also wanted to avoid using a network file share to host the files or wrap the site using Plain Text authentication.</p>
<p>The issue is Forms Authentication provides no security on the request stack within IIS 6 as it does in IIS 7. Because we can&#8217;t extend this, our files would be wide open to any attacker or malicious employee looking to download the file by figuring out the link or by users who had bookmarked certain files and later after they had been removed from that role, being able to still access them.</p>
<h2>The Solution</h2>
<p>The solution seemed easy. Some content management systems allow you to store files in databases, or use URL re-writing to accomplish this task, but I wanted something simpler and easier to extend or duplicate in the future. We&#8217;re all pretty familiar with IHttpHandler and it seemed since that&#8217;s the way the prior, more complex solutions perform this feat more often than not, why not give it a shot for this: <span id="more-9"></span></p>
<h3>Setup</h3>
<p>In order for ASP.NET to recognize the request for the PDF file and wrap it with the configured authentication method, we have to tell IIS to use the same ASAPI engine that is uses for ASPX, ASMX, etc.</p>
<p>I opened the properties for the web site/virtual directory in IIS Manager, clicked on the Configurationâ€¦ button located within the application settings section and the first tab contains my ISAPI extensions:</p>
<p><img src="/files/040408_0532_ProtectingP1.jpg" alt="" width="504" height="476" /></p>
<p>Then, I clicked the &#8220;Addâ€¦&#8221; button to add the new .pdf extension using the same ASP.NET ISAPI DLL, c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll for GET requests of .pdf:</p>
<p><img src="/files/040408_0532_ProtectingP2.jpg" alt="" width="504" height="293" /></p>
<p>I&#8217;m using the &#8220;Verify that file exists&#8221; because the file really will exists, it&#8217;s not in a database or remote location or anything fancy like that.</p>
<p>Once that&#8217;s done, you&#8217;ll notice if you have security set up on your site and in your web.config file around a PDF file, say for:</p>
<p>&lt;location path=&#8221;MyFile.pdf&#8221;&gt;&lt;web.config&gt;&lt;authorization&gt;&lt;deny users=&#8221;?&#8221; /&gt;&lt;/authorization&gt;&lt;/web.config&gt;&lt;/location&gt;</p>
<p>And you are not authenticated; you will immediately be taken to the login screen. Once you log in however you will get a compilation error page. This is because the ASP.NET CLR is trying to compile/execute your PDF as an ASP.NET extension file and it cannot for obvious reasons, it doesn&#8217;t know how to handle your file.</p>
<h3>IHttpHandler</h3>
<p>Now that security is taken care of, I needed to let ASP.NET know what to do with a PDF file. To do this I needed to create a simple IHttpHandler:</p>
<p><span style="font-size: 7pt; font-family: Courier New"><span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">PdfHandler</span> : IHttpHandler </span><br />
<span style="font-size: 7pt; font-family: Courier New">{ </span><br />
<span style="font-size: 7pt; font-family: Courier New">Â Â Â Â <span style="color: blue">public</span> PdfHandler() { } </span><br />
<span style="font-size: 7pt; font-family: Courier New">Â Â Â Â <span style="color: blue">public</span> <span style="color: blue">void</span> ProcessRequest(HttpContext context) </span><br />
<span style="font-size: 7pt; font-family: Courier New">Â Â Â Â { </span><br />
<span style="font-size: 7pt; font-family: Courier New">Â Â Â Â Â Â Â Â <span style="color: blue">string</span> path = context.Request.PhysicalPath; </span><br />
<span style="font-size: 7pt; font-family: Courier New">Â Â Â Â Â Â Â Â <span style="color: blue">string</span> name = path.Split(<span style="color: #a31515">&#8216;\\&#8217;</span>)[path.Split(<span style="color: #a31515">'\\'</span>).Length - 1]; </span><br />
<span style="font-size: 7pt; font-family: Courier New">Â Â Â Â Â Â Â Â <span style="color: blue">if</span> (!<span style="color: blue">string</span>.IsNullOrEmpty(path) &amp;&amp; path.ToLower().EndsWith(<span style="color: #a31515">&#8220;.pdf&#8221;</span>)) </span><br />
<span style="font-size: 7pt; font-family: Courier New">Â Â Â Â Â Â Â Â { </span><br />
<span style="font-size: 7pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â context.Response.ClearHeaders(); </span><br />
<span style="font-size: 7pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â context.Response.ClearContent(); </span><br />
<span style="font-size: 7pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â context.Response.Clear(); </span></p>
<p><span style="font-size: 7pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â context.Response.Charset = <span style="color: blue">null</span>; </span><br />
<span style="font-size: 7pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â context.Response.ContentType = <span style="color: #a31515">&#8220;application/pdf&#8221;</span>; </span><br />
<span style="font-size: 7pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â context.Response.AddHeader(<span style="color: #a31515">&#8220;Content-Type&#8221;</span>, <span style="color: #a31515">&#8220;application/pdf&#8221;</span>); </span><br />
<span style="font-size: 7pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â context.Response.AppendHeader(<span style="color: #a31515">&#8220;Content-Disposition&#8221;</span>, <span style="color: blue">string</span>.Format(<span style="color: #a31515">&#8220;inline;filename={0}&#8221;</span>, name)); </span><br />
<span style="font-size: 7pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â context.Response.WriteFile(path); </span><br />
<span style="font-size: 7pt; font-family: Courier New">Â Â Â Â Â Â Â Â } </span><br />
<span style="font-size: 7pt; font-family: Courier New">Â Â Â Â Â Â Â Â <span style="color: blue">else </span></span><br />
<span style="font-size: 7pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â <span style="color: blue">throw</span> <span style="color: blue">new</span> <span style="color: #2b91af">FileNotFoundException</span>(<span style="color: #a31515">&#8220;The page requested is invalid&#8221;</span>, path); </span><br />
<span style="font-size: 7pt; font-family: Courier New">Â Â Â Â } </span><br />
<span style="font-size: 7pt; font-family: Courier New">Â Â Â Â <span style="color: blue">public</span> <span style="color: blue">bool</span> IsReusable { <span style="color: blue">get</span> { <span style="color: blue">return</span> <span style="color: blue">false</span>; } } </span><br />
<span style="font-size: 7pt; font-family: Courier New">} </span></p>
<p>This class, PdfHandler, implements the IHttpHandler interface which implements a proper, IsReuseable (which this one is not) and a method, ProcessRequest, which does the dirty work using the passed in HttpContext. In this case, I get the physcial path of the file being requested (remember that the file should always exist, otherwise IIS would have kicked the request back out) and then parse the name of the file, double check (using some sanity checking) that the file is indeed a PDF that we&#8217;re dealing with, clearing the response, setting the MIME type in the header and using the Response.WriteFile(filePath) method to output the file directly through the buffered response stream to the client. This would all be transparent to the user and the response time, although not as fast as IIS serving the file directly, is still acceptible for my means of use.</p>
<h3>Web.Config Changes</h3>
<p>Once I had the handler written for my PDF files, I just needed to let ASP.NET on the application level to use my handler for all PDF requests coming into the virtual directory/web site. I did this by using the configuration section under &lt;web.config&gt;, &lt;httpHandlers&gt;:</p>
<p><span style="font-size: 7pt; font-family: Courier New"><span style="color: blue">&lt;</span><span style="color: #a31515">httpHandlers</span><span style="color: blue">&gt; </span></span><br />
<span style="font-size: 7pt; font-family: Courier New"><span style="color: blue">Â Â Â Â &lt;</span><span style="color: #a31515">add</span><span style="color: blue"> </span><span style="color: red">verb</span><span style="color: blue">=</span>&#8220;<span style="color: blue">GET</span>&#8220;<span style="color: blue"> </span><span style="color: red">path</span><span style="color: blue">=</span>&#8220;<span style="color: blue">*.pdf</span>&#8220;<span style="color: blue"> </span><span style="color: red">type</span><span style="color: blue">=</span>&#8220;<span style="color: blue">PdfHandler</span>&#8220;<span style="color: blue"> </span><span style="color: red">validate</span><span style="color: blue">=</span>&#8220;<span style="color: blue">false</span>&#8220;<span style="color: blue">/&gt; </span></span><br />
<span style="font-size: 7pt; font-family: Courier New"><span style="color: blue">&lt;/</span><span style="color: #a31515">httpHandlers</span><span style="color: blue">&gt; </span></span></p>
<p>With this entry in there now, everything is working great and now my web master and I can manage security in the application simply by adding folders and new web.config files with an &lt;authorization/&gt; section along with the built-in membership/role management that comes standard in ASP.NET application services.</p>
<p>Now if only I can get them on IIS 7, this entire article would become obsolete, but life would definitely be better!</p>
<p><a href="http://www.chadscharf.com/index.php/2008/04/protecting-pdf-files-in-iis-6-using-forms-authentication/">Protecting PDF files in IIS 6 using Forms Authentication</a> is a post from: <a href="http://www.chadscharf.com">Chad Scharf&#039;s Weblog</a>. For software consulting services please visit <a href="http://www.scharfholdings.com">Scharf Holdings, LLC</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.chadscharf.com/index.php/2008/04/protecting-pdf-files-in-iis-6-using-forms-authentication/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>You canâ€™t always blame Bill when Vista breaks</title>
		<link>http://www.chadscharf.com/index.php/2008/01/you-can%e2%80%99t-always-blame-bill-when-vista-breaks/</link>
		<comments>http://www.chadscharf.com/index.php/2008/01/you-can%e2%80%99t-always-blame-bill-when-vista-breaks/#comments</comments>
		<pubDate>Sat, 12 Jan 2008 02:51:00 +0000</pubDate>
		<dc:creator>Chad</dc:creator>
				<category><![CDATA[IIS7]]></category>
		<category><![CDATA[Windows Vista]]></category>
		<category><![CDATA[dcom]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[vista]]></category>

		<guid isPermaLink="false">http://chadscharf.com/post.aspx?id=c6b4a9a3-40ed-49d1-965e-60d11156ccc0</guid>
		<description><![CDATA[Just recently I decided to upgrade my development machine at the office from Windows XP to Windows Vista. Taking into consideration the ability to play around with the new IIS7, as well as take the opportunity to upgrade to Visual Studio 2008 Team Suite. I can say I&#8217;m happy that I did, I even did [...]<p><a href="http://www.chadscharf.com/index.php/2008/01/you-can%e2%80%99t-always-blame-bill-when-vista-breaks/">You canâ€™t always blame Bill when Vista breaks</a> is a post from: <a href="http://www.chadscharf.com">Chad Scharf&#039;s Weblog</a>. For software consulting services please visit <a href="http://www.scharfholdings.com">Scharf Holdings, LLC</a></p>
]]></description>
			<content:encoded><![CDATA[<p>Just recently I decided to upgrade my development machine at the office from Windows XP to Windows Vista. Taking into consideration the ability to play around with the new IIS7, as well as take the opportunity to upgrade to Visual Studio 2008 Team Suite. I can say I&#8217;m happy that I did, I even did a clean install since Vista Enterprise did not support an upgrade from XP. Then the fun started. After spending a day and a half re-installing all of my development tools, MS Office, hunting down new drivers for the video card, sound card as well as running Windows Updates, etc I was up and running without a care in the world. <span id="more-11"></span></p>
<h2>Administrator Mode</h2>
<p>OK, so Visual Studio 2008 likes to run with elevated privileges in order to access web sites on the local IIS server. That&#8217;s not so bad aside from losing the ability to drag and drop items into the IDE from Explorer. Then, about 4 weeks into using Windows Vista and Visual Studio 2008, I hit an odd snag. About 3 weeks ago I went to open a solution containing a web project, only to get this all too familiar message:</p>
<p><em>To access local IIS Web sites, you must run Visual Studio in the context of an administrator account. By default, Windows runs applications in a limited-privilege user account even when you are logged on to the computer as an administrator. To run Visual Studio with administrative privileges, right-click the Visual Studio icon and then click &#8216;Run as administrator. </em></p>
<p style="text-align: center"><img title="To access local IIS Web sites, you must run Visual Studio in the context of an administrator account. By default, Windows runs applications in a limited-privilege user account even when you are logged on to the computer as an administrator. To run Visual Studio with administrative privileges, right-click the Visual Studio icon and then click 'Run as administrator." src="/files/011208_0551_Youcantalwa1.gif" alt="To access local IIS Web sites, you must run Visual Studio in the context of an administrator account. By default, Windows runs applications in a limited-privilege user account even when you are logged on to the computer as an administrator. To run Visual Studio with administrative privileges, right-click the Visual Studio icon and then click 'Run as administrator." width="532" height="324" /><em> </em></p>
<p>Turns out, I WAS running Visual Studio under Administrative mode; however it didn&#8217;t seem to be recognizing this fact. After cursing Bill a few times I closed Visual Studio, re-opened it from the actual executable itself running as administrator; same deal. I rebooting my computer only to find that it still did not work, and on top of that my sound card was not working, however device manager said that is was operational and no errors were reported in any of the Event logs.</p>
<p>Now, no web projects and no sound card, what&#8217;s next? I open up the IIS7 manager to check on my web settings when I find this:</p>
<p style="text-align: center"><img style="width: 530px; height: 208px;" src="/files/011208_0551_Youcantalwa2.gif" alt="" width="530" height="208" /></p>
<p>The red &#8220;X&#8221; on the Default Web Site and a status of &#8220;Access Denied&#8221; for the web site in the web site list. I go to check my applications pools, and sure enough, the same thing:</p>
<p style="text-align: center"><img src="/files/011208_0551_Youcantalwa3.gif" alt="" width="543" height="286" /></p>
<p>The odd thing about all of this was that I could still access all of the sites in my Default Web Site, either using the &#8220;Browse&#8221; command from the IIS Manager or simply opening Internet Explorer and going to http://localhost/whatever. I attempted to run Windows Update which also gave me cryptic errors such as &#8220;WAS does not appear to be enabled&#8221;. This was about the time I opened a support ticket with Microsoft.</p>
<h2>Tinker Not</h2>
<p>Little did I realize as I told the IIS team support technician that there were no recent changes to my computer. There was however one significant detail that I didn&#8217;t think was significant at the time: I had rebooted my computer. Typically I simply lock my workstation for the night or for the weekend and perhaps reboot once every other month. Turns out the day before this all started happening I had rebooted my machine for the 3<sup>rd</sup> time since installing Windows Vista, this was a mistake.</p>
<p>Turns out when you change DCOM security settings on your machine using <strong><em>dcomcnfg</em></strong>, and Windows Vista warns you that things may stop working, and you ignore these warning it&#8217;s really YOUR fault your machine sucks and not Microsoft&#8217;s. After all, I was warned when I inadvertently tried to fully open all DCOM and MSDTC permissions on my box which I was accustomed to doing COM development on previous versions of Windows. Two little drop down boxes that I had set were the cause for all of this grief, &#8220;<strong>DCOM Default Authentication Level</strong>&#8221; and &#8220;<strong>Default Impersonation Level</strong>&#8220;.</p>
<p>These were the settings I had chosen without guidance or really much thought:</p>
<p style="text-align: center"><img src="/files/011208_0551_Youcantalwa4.gif" alt="" width="418" height="566" /></p>
<p>Turns out these configuration changes are BAD! Do not do this unless you want a Vista pile of worthless garbage under your desk. Of course these changes didn&#8217;t start affecting services until I had rebooted, a couple of weeks after making this change which I had completely forgotten about.</p>
<p>Below is what I should have kept, and sure enough shortly after resetting these and rebooting not only did IIS 7 begin working again as expected, Visual Studio, my sound card, Windows Update, my CD Burner as well as my sanity were back in check as well.</p>
<p style="text-align: center"><img src="/files/011208_0551_Youcantalwa5.gif" alt="" width="418" height="566" /></p>
<p>It was all thanks to this <a href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1387492&amp;SiteID=1">post</a> that I found on an MSDN forum while trying to troubleshoot my sound card that lead to start looking at COM permissions. I followed all the steps in this post and many more similar ones to no avail, until I vaguely remember screwing around with the DCOM security configuration and more importantly the nice warning message this had given me when I changes those settings. Sure enough after changing them back I&#8217;m back in business and promise to never ignore Bill again.</p>
<h2>Thanks Bill</h2>
<p>So you can say what you want about Microsoft and Windows Vista, but I love it and can&#8217;t wait for some of the new and emerging stuff that&#8217;s soon to come. After all, had I been using Linux or a Mac, the OS would have let me be stupid without a warning and I would have never been the wiser. So for those developers and techies that like to tinker, the best of luck to ya, I&#8217;m sticking to Windows defaults from here on out, they&#8217;re really not that bad anyway.</p>
<p><a href="http://www.chadscharf.com/index.php/2008/01/you-can%e2%80%99t-always-blame-bill-when-vista-breaks/">You canâ€™t always blame Bill when Vista breaks</a> is a post from: <a href="http://www.chadscharf.com">Chad Scharf&#039;s Weblog</a>. For software consulting services please visit <a href="http://www.scharfholdings.com">Scharf Holdings, LLC</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.chadscharf.com/index.php/2008/01/you-can%e2%80%99t-always-blame-bill-when-vista-breaks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

