<?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>Tobin Titus &#187; canonicalization</title>
	<atom:link href="http://tobint.com/blog/tag/canonicalization/feed/" rel="self" type="application/rss+xml" />
	<link>http://tobint.com</link>
	<description>You Are What You Don&#039;t Automate</description>
	<lastBuildDate>Fri, 03 Feb 2012 23:05:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Canonicalization issues and File Paths</title>
		<link>http://tobint.com/blog/canonicalization-issues-and-file-paths/</link>
		<comments>http://tobint.com/blog/canonicalization-issues-and-file-paths/#comments</comments>
		<pubDate>Fri, 06 Aug 2004 23:10:00 +0000</pubDate>
		<dc:creator>tobint</dc:creator>
				<category><![CDATA[technical]]></category>
		<category><![CDATA[canonicalization]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://tobint.com/Blog/Canonicalization-issues-and-File-Paths</guid>
		<description><![CDATA[I keep running into code lately that does some pretty elaborate security testing but in the end leaves a very large issue unaddressed &#8212; canonicalization errors related to file I/O. Michael Howard and David LeBlanc dedicated an entire chapter in Writing Secure Codeto the idea that “All Input is Evil“. The concept is that you [...]
Related posts:<ol>
<li><a href='http://tobint.com/blog/file-uploading-in-a-web-environment-part-1/' rel='bookmark' title='File uploading in a web environment'>File uploading in a web environment</a></li>
<li><a href='http://tobint.com/blog/string-format-vs-stringbuilder-appendformat/' rel='bookmark' title='String.Format vs StringBuilder.AppendFormat'>String.Format vs StringBuilder.AppendFormat</a></li>
<li><a href='http://tobint.com/blog/more-string-stringbuilder-quirks/' rel='bookmark' title='More String / StringBuilder Quirks'>More String / StringBuilder Quirks</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftobint.com%2Fblog%2Fcanonicalization-issues-and-file-paths%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftobint.com%2Fblog%2Fcanonicalization-issues-and-file-paths%2F&amp;source=tobint&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I keep running into code lately that does some pretty elaborate security testing but in the end leaves a very large issue unaddressed &#8212; canonicalization errors related to file I/O.</p>
<p>Michael Howard and David LeBlanc dedicated an entire chapter in </font><a href="http://www.microsoft.com/mspress/books/5957.asp">Writing Secure Code</a>to the idea that “All Input is Evil“.  The concept is that you should not rely on the fact that input coming from any source &#8212; trusted or not is going to be in a format that you accept.  You should validate, validate, and validate again even if your I/O function isn&#8217;t intended to access anything of great importance.</p>
<p>Canonicalization is the process of breaking something down to it&#8217;s most simple form.  Let&#8217;s take a look at an example:</p>
<p><font face="Courier New" color=#000080 size=2>public FileStream OpenFile( string fileName )<br />{<br />string fullPath = string.Format(@&#8221;C:\inetpub\wwwroot\{0}&#8221;, fileName);<br />return new FileStream(fullPath, FileMode, FileAccess);<br />}</font></p>
<p>You may have ony intended to give this function access to code stored in the default web root. But what would happen if someone called your function like this:</p>
<p><font face="Arial" color="#000080" size="2">File f = OpenFile(”..\\..\\windows\\system32\\config\\sam”);</font></p>
<p>The elipsis at the begining of the path would direct the file to go up a directory and doing it twice would put the user at your root directory, giving someone access to your entire file system.  </p>
<p>You could use a regular expression to check for this type of thing right? Well, yes, but it wouldn&#8217;t be enough.  Your regular expression would test for the “..\\” sequence, but what happens if someone encodes the path with %2E instead of the “.”.  Would your regular expression be smart enough to check for that? Probably not.  There are a ton of ways to represent a path differently and you should use many different forms of validation.  However, one of my favorite is to use the <font face="Arial" size="2">DirectoryInfo</font> and <font face="Courier New" size="2">FileInfo</font> “<font face="Courier New" size="2">FullName</font>” property.  Creating a new <font face="Courier New" size="2">FileInfo</font> instance passing it your intended path will break the path down into it&#8217;s actual meaning.  Once this is done, you can use the <font face="Courier New" size="2">FullName</font> member to obtain the canonicalized path.  As a matter of completion, here is some sample code to get you started:</p>
<p><font face="Courier New" color="#000080" size="2">public FileStream OpenFile( string fileName )<br />{<br />string fullPath = string.Format(@&#8221;C:\inetpub\wwwroot\{0}&#8221;, fileName);<br />string canonicalizedPath = new FileInfo(fullPath).FullName;<br />return new FileStream(canonicalizedPath, FileMode, FileAccess);<br />}</font></p>
<p>Another option available is to use the Path class as follows:</p>
<p><font face="Courier New" color="#000080" size="2">public FileStream OpenFile( string fileName )<br />{<br />string fullPath = string.Format(@&#8221;C:\inetpub\wwwroot\{0}&#8221;, fileName);<br />string canonicalizedPath = Path.GetFullPath(fullPath);<br />return new FileStream(canonicalizedPath, FileMode, FileAccess);<br />}</font></p>
<p>This performs the same work under the covers without creating a FileInfo instance.</p>
<p>This example does not explain everything that a dilligent coder worried about security should do to secure this method, but it should demonstrate the usefulness of the <font face="Courier New" size="2">FullName</font> member in validating file paths.</p>
<p>Related posts:<ol>
<li><a href='http://tobint.com/blog/file-uploading-in-a-web-environment-part-1/' rel='bookmark' title='File uploading in a web environment'>File uploading in a web environment</a></li>
<li><a href='http://tobint.com/blog/string-format-vs-stringbuilder-appendformat/' rel='bookmark' title='String.Format vs StringBuilder.AppendFormat'>String.Format vs StringBuilder.AppendFormat</a></li>
<li><a href='http://tobint.com/blog/more-string-stringbuilder-quirks/' rel='bookmark' title='More String / StringBuilder Quirks'>More String / StringBuilder Quirks</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://tobint.com/blog/canonicalization-issues-and-file-paths/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

