<?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>JonnyReeves.co.uk &#187; model</title>
	<atom:link href="http://www.jonnyreeves.co.uk/tag/model/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jonnyreeves.co.uk</link>
	<description>Actionscript, Flash, PHP and stuff</description>
	<lastBuildDate>Mon, 19 Jul 2010 15:36:14 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>CakePHP &#8211; Uploaded File Validation in Models</title>
		<link>http://www.jonnyreeves.co.uk/2008/06/cakephp-uploaded-file-validation-in-models/</link>
		<comments>http://www.jonnyreeves.co.uk/2008/06/cakephp-uploaded-file-validation-in-models/#comments</comments>
		<pubDate>Sun, 01 Jun 2008 14:56:26 +0000</pubDate>
		<dc:creator>Jonny</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[file upload]]></category>
		<category><![CDATA[model]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[validation]]></category>

		<guid isPermaLink="false">http://www.jonnyreeves.co.uk/?p=37</guid>
		<description><![CDATA[Allowing uploaded files from users in PHP is fraught with danger, however by using CakePHP 1.2 and a little bit of Validation magic we can make things a little safer.
First, lets start by creating a simple upload form where the users will be uploading their files

&#60;?php
# /app/views/story/create.ctp
echo $form-&#62;create&#40;&#8216;Story&#8217;, array&#40;&#8216;action&#8217; =&#62; &#8216;create&#8217;, &#8216;type&#8217; =&#62; &#8216;file&#8217;&#41;&#41;;
echo $form-&#62;input&#40;&#8216;Story.title&#8217;&#41;;
echo [...]]]></description>
			<content:encoded><![CDATA[<p>Allowing uploaded files from users in PHP is fraught with danger, however by using CakePHP 1.2 and a little bit of Validation magic we can make things a little safer.</p>
<p>First, lets start by creating a simple upload form where the users will be uploading their files</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="kw2">&lt;?php</span><br />
<span class="co2"># /app/views/story/create.ctp</span><br />
<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$form</span>-&gt;<span class="me1">create</span><span class="br0">&#40;</span><span class="st0">&#8216;Story&#8217;</span>, <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;action&#8217;</span> =&gt; <span class="st0">&#8216;create&#8217;</span>, <span class="st0">&#8216;type&#8217;</span> =&gt; <span class="st0">&#8216;file&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$form</span>-&gt;<span class="me1">input</span><span class="br0">&#40;</span><span class="st0">&#8216;Story.title&#8217;</span><span class="br0">&#41;</span>;<br />
<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$form</span>-&gt;<span class="me1">input</span><span class="br0">&#40;</span><span class="st0">&#8216;Story.contents&#8217;</span><span class="br0">&#41;</span>;<br />
<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$form</span>-&gt;<span class="me1">input</span><span class="br0">&#40;</span><span class="st0">&#8216;Artwork.uploaded_image&#8217;</span>, <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;type&#8217;</span> =&gt; <span class="st0">&#8216;file&#8217;</span>, <span class="st0">&#8216;label&#8217;</span> =&gt; <span class="st0">&#8216;Front Artwork&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$form</span>-&gt;<span class="me1">end</span><span class="br0">&#40;</span><span class="st0">&#8216;Create Story&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="kw2">?&gt;</span><br />
&nbsp;</div>
<p>Nothing particularly special here, just to note that we are specifying &#8220;type&#8221; => &#8220;file&#8221; in the $form::create method &#8211; this makes cake inset the correct &#8216;enc-type&#8217; value in the generated<br />
<form> tag.</p>
<p>So when the user submits this form, they will be pointed towards the create() action in the StoryController, lets have a look at that:</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="kw2">&lt;?php</span><br />
<span class="co2"># /app/controllers/story_controller.php</span><br />
uses<span class="br0">&#40;</span><span class="st0">&#8217;sanitize&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="kw2">class</span> StoryController <span class="kw2">extends</span> AppController <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$name</span> = <span class="st0">&#8216;Story&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Allows users to create a story with an attached image.<br />
&nbsp; &nbsp; &nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">function</span> create<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Always sanitize user input, except for the filename (which will get borked on Win32 systems)</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$uploaded_image</span> = <span class="re0">$this</span>-&gt;<span class="me1">data</span><span class="br0">&#91;</span><span class="st0">&#8216;Artwork&#8217;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#8216;uploaded_image&#8217;</span><span class="br0">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">data</span> = Sanitize::<span class="me2">clean</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">data</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">data</span><span class="br0">&#91;</span><span class="st0">&#8216;Artwork&#8217;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#8216;uploaded_image&#8217;</span><span class="br0">&#93;</span> = <span class="re0">$uploaded_image</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">Story</span>-&gt;<span class="me1">save</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// redirect to the new story.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">Session</span>-&gt;<span class="me1">setFlash</span><span class="br0">&#40;</span><span class="st0">&#8216;Your story was created!&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$insert_id</span> = <span class="re0">$this</span>-&gt;<span class="me1">Story</span>-&gt;<span class="me1">getInsertID</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">redirect</span><span class="br0">&#40;</span><span class="st0">&#8216;/stories/view/&#8217;</span> . <span class="re0">$insert_id</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">Session</span>-&gt;<span class="me1">setFlash</span><span class="br0">&#40;</span><span class="st0">&#8216;Please correct the errors below&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<span class="kw2">?&gt;</span><br />
&nbsp;</div>
<p>Again, nothing unusual here, however, without any data validation we would be opening the application up to attack from malicious users &#8211; they could upload PHP code that could later be executed; for more general reading on the woes of File uploads, see what Chris Shiftlett, author of <a href="http://www.amazon.co.uk/Essential-PHP-Security-Chris-Shiflett/dp/059600656X/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1212331543&#038;sr=8-1">Essential PHP Security</a> <a href="http://shiflett.org/articles/file-uploads">has to say</a>.</p>
<p>So, in order to add some security to Image uploads, we are going to add some simple custom validation rules to the Artwork Model:</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="kw2">&lt;?php</span><br />
<span class="co2"># /app/models/artwork.php</span><br />
<span class="kw2">Class</span> Artwork <span class="kw2">extends</span> AppModel <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$name</span> = <span class="st0">&#8216;Artwork&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$validate</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a> <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;uploaded_image&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a> <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;valid_upload&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a> <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;rule&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;validateUploadedFile&#8217;</span>, <span class="kw2">false</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;message&#8217;</span> =&gt; <span class="st0">&#8216;An error occurred whilst uploading&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Custom validation rule for uploaded files.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* &nbsp;@param Array $data CakePHP File info.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* &nbsp;@param Boolean $required Is this field required?<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* &nbsp;@return Boolean<br />
&nbsp; &nbsp; &nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">function</span> validateUploadedFile<span class="br0">&#40;</span><span class="re0">$data</span>, <span class="re0">$required</span> = <span class="kw2">false</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Remove first level of Array ($data['Artwork']['size'] becomes $data['size'])</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$upload_info</span> = <a href="http://www.php.net/array_shift"><span class="kw3">array_shift</span></a><span class="br0">&#40;</span><span class="re0">$data</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// No file uploaded.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$required</span> &amp;&amp; <span class="re0">$upload_info</span><span class="br0">&#91;</span><span class="st0">&#8217;size&#8217;</span><span class="br0">&#93;</span> == <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Check for Basic PHP file errors.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$upload_info</span><span class="br0">&#91;</span><span class="st0">&#8216;error&#8217;</span><span class="br0">&#93;</span> !== <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Finally, use PHP&#8217;s own file validation method.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <a href="http://www.php.net/is_uploaded_file"><span class="kw3">is_uploaded_file</span></a><span class="br0">&#40;</span><span class="re0">$upload_info</span><span class="br0">&#91;</span><span class="st0">&#8216;tmp_name&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<span class="kw2">?&gt;</span><br />
&nbsp;</div>
<p>Now, before the Data from the form is saved, it will be passed through the custom validation above &#8211; any invalid, or potentially malicious files will be rejected.  This could easily be split into separate validation methods to provide more understandable error messages for your users.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonnyreeves.co.uk/2008/06/cakephp-uploaded-file-validation-in-models/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
