<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress/2.1.3" -->
<rss version="2.0" 
	xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
	<title>Comments for Youruby.net</title>
	<link>http://www.youruby.net</link>
	<description>creative works of james rubenstein</description>
	<pubDate>Thu, 21 Aug 2008 14:13:56 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.1.3</generator>

	<item>
		<title>Comment on How not to get hacked: uploaded files in PHP by Alex Songe</title>
		<link>http://www.youruby.net/2007/09/how-not-to-get-hacked-uploaded-files-in-php/#comment-14</link>
		<author>Alex Songe</author>
		<pubDate>Wed, 19 Sep 2007 20:46:32 +0000</pubDate>
		<guid>http://www.youruby.net/2007/09/how-not-to-get-hacked-uploaded-files-in-php/#comment-14</guid>
					<description>I think you need to make it clear what things you're protecting against.

Using server-side mime type libs is the best thing for ascertaining the type of file it is.

Using extension checking is the way you make sure you're not writing something a cgi processor would execute (because that's how most webservers recognize that it's to be executed, amazingly).

Mime magic will check in a sane manner the type of file, but you will still not know if it's a valid image file.  By using gd and/or imagemagick to immediately resize the image to some type of max height and then always saving it as a jpeg is a fairly valid way.  Imagemagick even has ping functions for this.

Putting stuff outside the webroot limits the visibility of the file, you don't have to rely on the webserver's config (or lack thereof).  Though you'd have to be insane to make jpeg map to some type of cgi handler.

Instead of saying "Do these things to make your app secure" it should be said "These are some known vectors, and this is how you stop this vector" etc.

I consider putting shit outside the webroot as "Putting the gun on top of the cabinets so the kid doesn't get to it." It doesn't make the gun less dangerous, it just means only the adults get to use it.</description>
		<content:encoded><![CDATA[<p>I think you need to make it clear what things you&#8217;re protecting against.</p>
<p>Using server-side mime type libs is the best thing for ascertaining the type of file it is.</p>
<p>Using extension checking is the way you make sure you&#8217;re not writing something a cgi processor would execute (because that&#8217;s how most webservers recognize that it&#8217;s to be executed, amazingly).</p>
<p>Mime magic will check in a sane manner the type of file, but you will still not know if it&#8217;s a valid image file.  By using gd and/or imagemagick to immediately resize the image to some type of max height and then always saving it as a jpeg is a fairly valid way.  Imagemagick even has ping functions for this.</p>
<p>Putting stuff outside the webroot limits the visibility of the file, you don&#8217;t have to rely on the webserver&#8217;s config (or lack thereof).  Though you&#8217;d have to be insane to make jpeg map to some type of cgi handler.</p>
<p>Instead of saying &#8220;Do these things to make your app secure&#8221; it should be said &#8220;These are some known vectors, and this is how you stop this vector&#8221; etc.</p>
<p>I consider putting shit outside the webroot as &#8220;Putting the gun on top of the cabinets so the kid doesn&#8217;t get to it.&#8221; It doesn&#8217;t make the gun less dangerous, it just means only the adults get to use it.</p>
]]></content:encoded>
				</item>
	<item>
		<title>Comment on How not to get hacked: uploaded files in PHP by jim</title>
		<link>http://www.youruby.net/2007/09/how-not-to-get-hacked-uploaded-files-in-php/#comment-13</link>
		<author>jim</author>
		<pubDate>Wed, 19 Sep 2007 20:45:13 +0000</pubDate>
		<guid>http://www.youruby.net/2007/09/how-not-to-get-hacked-uploaded-files-in-php/#comment-13</guid>
					<description>You raise some interesting points.  But I'd like to point out that I wasn't suggesting to use GD/Image Magick to validate your uploads unless you actually needed to thumbnail your images.  Doing so would be unnecessary overhead and would be silly.  Also - a point that I didn't mention, I'd save the thumbnailed images inside the webroot, allowing them to be served by the webserver and not via a serving php script, which the server is absolutely better at than php.

As far as reusing a MIME type which was originally specified by the client; If you validate this MIME-type before you save your file, there is no reason you couldn't do this.

Obviously using the client specified MIME blindly is horrible, bad, and wrong as we've thoroughly outlined in both our posts, but this obviously isn't common knowledge, nor is where to save files once their uploaded, or even how to validate them.  I was simply saying that trusting the user, and the user's content to be usable from the get-go is web development 101.</description>
		<content:encoded><![CDATA[<p>You raise some interesting points.  But I&#8217;d like to point out that I wasn&#8217;t suggesting to use GD/Image Magick to validate your uploads unless you actually needed to thumbnail your images.  Doing so would be unnecessary overhead and would be silly.  Also - a point that I didn&#8217;t mention, I&#8217;d save the thumbnailed images inside the webroot, allowing them to be served by the webserver and not via a serving php script, which the server is absolutely better at than php.</p>
<p>As far as reusing a MIME type which was originally specified by the client; If you validate this MIME-type before you save your file, there is no reason you couldn&#8217;t do this.</p>
<p>Obviously using the client specified MIME blindly is horrible, bad, and wrong as we&#8217;ve thoroughly outlined in both our posts, but this obviously isn&#8217;t common knowledge, nor is where to save files once their uploaded, or even how to validate them.  I was simply saying that trusting the user, and the user&#8217;s content to be usable from the get-go is web development 101.</p>
]]></content:encoded>
				</item>
	<item>
		<title>Comment on How not to get hacked: uploaded files in PHP by Mike Seth</title>
		<link>http://www.youruby.net/2007/09/how-not-to-get-hacked-uploaded-files-in-php/#comment-11</link>
		<author>Mike Seth</author>
		<pubDate>Wed, 19 Sep 2007 20:01:20 +0000</pubDate>
		<guid>http://www.youruby.net/2007/09/how-not-to-get-hacked-uploaded-files-in-php/#comment-11</guid>
					<description>Hi!

Thanks for responding. I do not agree on all of your points, but I will update the post for clarity.

First, the file extensions are not, in itself, a problem. You can of course upload PHP code as a .jpeg file, but what good would it do to anyone if the webserver reads it as a JPEG image and streams it to the output verbatim? The "classic" file extension vulnerabilities are an entirely different class of client-side problems: typically, a client that parses the file name is unable to do so properly (think Outlook wrapping around a long file name that is stuffed with spaces and a .pif extension in the end). This is never the case in webservers, which rely on the file extension heavily. It would take a genuinely screwed up server configuration (e.g. a default handler set to PHP for &lt;em&gt;all&lt;/em&gt; kinds of files, something I'm not even sure is possible) to make  extension faking dangerous to the server. The client is another issue, but I mentioned that.

In fact, MIME type faking is more dangerous: first, people who don't understand HTTP do not really realize that it's an user-supplied value; second, if you only check the file extension and not the MIME type, you're taking a comparative risk that's way lesser than if you were to check only the MIME type and not the file extension. In other words, MIME type tests and not file extension tests are the loosest type of verification.

I also absolutely disagree regarding the "outside the document root" policies. If your trust check fails, it really doesn't matter whether you put the hostile file inside or outside the web root: your security has been violated anyway. On the other hand, when you move static documents out of the document root, you get a tremendous disadvantage of having to identify and pipe them to the user &lt;em&gt;yourself&lt;/em&gt; as opposed to letting the webserver do that for you (exactly what you mentioned) - the kind of thing that a webserver is designed for and is inherently better at than any of your PHP code. You gain zero security benefit and add an unnecessary burden on the server, plus there's now additional logic in your code that never should've been there in first place. Worse yet, people who succumb to the dumb idea of moving the documents out of webroot eventually fall into the trap of reusing the initial MIME type for the output headers, thus creating a goatsific security hole. It is not a web developer 101; it's a myth.

I would not necessarily go with GD/imagemagick processing either. Remember: these libraries are context aware, which means bugs in them can be exploited. Unless you actually need to produce thumbnails, you shouldn't use context-specific libraries to validate uploads. You are actually aggravating risks and not alleviating them.

The proper way to handle image upload locations is almost as you described, but in a production environment (on a single machine) you do it like this: 

The uploaded documents are stored under a separate webroot, and are available through a subdomain, served by a different webserver (lighty or thttpd, usually), which runs under different privileges and does &lt;strong&gt;not&lt;/strong&gt; have write permissions anywhere.

Uploads are authorized by a server script, and then queued in the database for a background (crontab) script with a different set of privileges. That script double checks the file contents and then moves them to the target location, where they are picked up by the other server that only serves static documents. This way, you retain complete isolation, enforce strict security, and do not get a performance impact. Better: you can do mod_rewrite magic, add caching headers, play with resource allocation between webservers according to your specific scenario or put a proxy in front of your whole static subdomain.  The downside? It's complicated. You need to be secure in your skills to set this kind of thing up &lt;em&gt;and&lt;/em&gt; maintain it in the future.</description>
		<content:encoded><![CDATA[<p>Hi!</p>
<p>Thanks for responding. I do not agree on all of your points, but I will update the post for clarity.</p>
<p>First, the file extensions are not, in itself, a problem. You can of course upload PHP code as a .jpeg file, but what good would it do to anyone if the webserver reads it as a JPEG image and streams it to the output verbatim? The &#8220;classic&#8221; file extension vulnerabilities are an entirely different class of client-side problems: typically, a client that parses the file name is unable to do so properly (think Outlook wrapping around a long file name that is stuffed with spaces and a .pif extension in the end). This is never the case in webservers, which rely on the file extension heavily. It would take a genuinely screwed up server configuration (e.g. a default handler set to PHP for <em>all</em> kinds of files, something I&#8217;m not even sure is possible) to make  extension faking dangerous to the server. The client is another issue, but I mentioned that.</p>
<p>In fact, MIME type faking is more dangerous: first, people who don&#8217;t understand HTTP do not really realize that it&#8217;s an user-supplied value; second, if you only check the file extension and not the MIME type, you&#8217;re taking a comparative risk that&#8217;s way lesser than if you were to check only the MIME type and not the file extension. In other words, MIME type tests and not file extension tests are the loosest type of verification.</p>
<p>I also absolutely disagree regarding the &#8220;outside the document root&#8221; policies. If your trust check fails, it really doesn&#8217;t matter whether you put the hostile file inside or outside the web root: your security has been violated anyway. On the other hand, when you move static documents out of the document root, you get a tremendous disadvantage of having to identify and pipe them to the user <em>yourself</em> as opposed to letting the webserver do that for you (exactly what you mentioned) - the kind of thing that a webserver is designed for and is inherently better at than any of your PHP code. You gain zero security benefit and add an unnecessary burden on the server, plus there&#8217;s now additional logic in your code that never should&#8217;ve been there in first place. Worse yet, people who succumb to the dumb idea of moving the documents out of webroot eventually fall into the trap of reusing the initial MIME type for the output headers, thus creating a goatsific security hole. It is not a web developer 101; it&#8217;s a myth.</p>
<p>I would not necessarily go with GD/imagemagick processing either. Remember: these libraries are context aware, which means bugs in them can be exploited. Unless you actually need to produce thumbnails, you shouldn&#8217;t use context-specific libraries to validate uploads. You are actually aggravating risks and not alleviating them.</p>
<p>The proper way to handle image upload locations is almost as you described, but in a production environment (on a single machine) you do it like this: </p>
<p>The uploaded documents are stored under a separate webroot, and are available through a subdomain, served by a different webserver (lighty or thttpd, usually), which runs under different privileges and does <strong>not</strong> have write permissions anywhere.</p>
<p>Uploads are authorized by a server script, and then queued in the database for a background (crontab) script with a different set of privileges. That script double checks the file contents and then moves them to the target location, where they are picked up by the other server that only serves static documents. This way, you retain complete isolation, enforce strict security, and do not get a performance impact. Better: you can do mod_rewrite magic, add caching headers, play with resource allocation between webservers according to your specific scenario or put a proxy in front of your whole static subdomain.  The downside? It&#8217;s complicated. You need to be secure in your skills to set this kind of thing up <em>and</em> maintain it in the future.</p>
]]></content:encoded>
				</item>
</channel>
</rss>
