From 820f7f257a01002a3cfc1f60544a784fa86056a1 Mon Sep 17 00:00:00 2001 From: drigato Date: Fri, 14 Mar 2014 17:34:56 -0400 Subject: [PATCH 1/2] CC-5733: RESTful API data sanitization and validation Stripped out fields that are readonly to the RESTful API from the request data for POST and PUT. Stripped out fields that should never be visible outside of Airtime in response data. Set uploaded and modified timestamp on POST request. Set modified timestamp on PUT request. --- .../rest/controllers/MediaController.php | 77 ++++++++++++++++--- 1 file changed, 65 insertions(+), 12 deletions(-) diff --git a/airtime_mvc/application/modules/rest/controllers/MediaController.php b/airtime_mvc/application/modules/rest/controllers/MediaController.php index 011f2eeff..6ad5d90cc 100644 --- a/airtime_mvc/application/modules/rest/controllers/MediaController.php +++ b/airtime_mvc/application/modules/rest/controllers/MediaController.php @@ -2,6 +2,26 @@ class Rest_MediaController extends Zend_Rest_Controller { + //fields that are not modifiable via our RESTful API + private $blackList = array( + 'id', + 'file_exists', + 'hidden', + 'silan_check', + 'soundcloud_id', + 'is_scheduled', + 'is_playlist' + ); + + //fields we should never expose through our RESTful API + private $privateFields = array( + 'file_exists', + 'hidden', + 'silan_check', + 'is_scheduled', + 'is_playlist' + ); + public function init() { $this->view->layout()->disableLayout(); @@ -13,10 +33,10 @@ class Rest_MediaController extends Zend_Rest_Controller return; } - $files_array = []; + $files_array = array(); foreach (CcFilesQuery::create()->find() as $file) { - array_push($files_array, $file->toArray(BasePeer::TYPE_FIELDNAME)); + array_push($files_array, $this->sanitize($file)); } $this->getResponse() @@ -42,11 +62,10 @@ class Rest_MediaController extends Zend_Rest_Controller $file = CcFilesQuery::create()->findPk($id); if ($file) { - //TODO: Strip or sanitize the JSON output $this->getResponse() ->setHttpResponseCode(200) - ->appendBody(json_encode($file->toArray(BasePeer::TYPE_FIELDNAME))); + ->appendBody(json_encode($this->sanitize($file))); } else { $this->fileNotFoundResponse(); } @@ -66,18 +85,20 @@ class Rest_MediaController extends Zend_Rest_Controller return; } - //TODO: Strip or sanitize the JSON output $file = new CcFiles(); - $file->fromArray($this->getRequest()->getPost()); + $file->fromArray($this->validateRequestData($this->getRequest()->getPost())); $file->setDbOwnerId($this->getOwnerId()); + $now = new DateTime("now", new DateTimeZone("UTC")); + $file->setDbUtime($now); + $file->setDbMtime($now); $file->save(); - + $callbackUrl = $this->getRequest()->getScheme() . '://' . $this->getRequest()->getHttpHost() . $this->getRequest()->getRequestUri() . "/" . $file->getPrimaryKey(); $this->processUploadedFile($callbackUrl); - + $this->getResponse() ->setHttpResponseCode(201) - ->appendBody(json_encode($file->toArray(BasePeer::TYPE_FIELDNAME))); + ->appendBody(json_encode($this->sanitize($file))); } public function putAction() @@ -94,12 +115,13 @@ class Rest_MediaController extends Zend_Rest_Controller if ($file) { //TODO: Strip or sanitize the JSON output - - $file->fromArray(json_decode($this->getRequest()->getRawBody(), true), BasePeer::TYPE_FIELDNAME); + $file->fromArray($this->validateRequestData(json_decode($this->getRequest()->getRawBody(), true)), BasePeer::TYPE_FIELDNAME); + $now = new DateTime("now", new DateTimeZone("UTC")); + $file->setDbMtime($now); $file->save(); $this->getResponse() ->setHttpResponseCode(200) - ->appendBody(json_encode($file->toArray(BasePeer::TYPE_FIELDNAME))); + ->appendBody(json_encode($this->sanitize($file))); } else { $this->fileNotFoundResponse(); } @@ -224,5 +246,36 @@ class Rest_MediaController extends Zend_Rest_Controller Logging::info($e->getMessage()); } } + + /** + * + * Strips out fields from incoming request data that should never be modified + * from outside of Airtime + * @param array $data + */ + private function validateRequestData($data) + { + foreach ($this->blackList as $key) { + unset($data[$key]); + } + + return $data; + } + + /** + * + * Strips out the private fields we do not want to send back in API responses + */ + //TODO: rename this function? + public function sanitize($file) + { + $response = $file->toArray(BasePeer::TYPE_FIELDNAME); + + foreach ($this->privateFields as $key) { + unset($response[$key]); + } + + return $response; + } } From 65ab49baee6657a86377c3571e4260c81bb5e31c Mon Sep 17 00:00:00 2001 From: drigato Date: Fri, 14 Mar 2014 17:53:03 -0400 Subject: [PATCH 2/2] CC-5733: RESTful API data sanitization and validation Renamed sanitize function to sanitizeResponse --- .../modules/rest/controllers/MediaController.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/airtime_mvc/application/modules/rest/controllers/MediaController.php b/airtime_mvc/application/modules/rest/controllers/MediaController.php index 6ad5d90cc..80d3b1656 100644 --- a/airtime_mvc/application/modules/rest/controllers/MediaController.php +++ b/airtime_mvc/application/modules/rest/controllers/MediaController.php @@ -36,7 +36,7 @@ class Rest_MediaController extends Zend_Rest_Controller $files_array = array(); foreach (CcFilesQuery::create()->find() as $file) { - array_push($files_array, $this->sanitize($file)); + array_push($files_array, $this->sanitizeResponse($file)); } $this->getResponse() @@ -65,7 +65,7 @@ class Rest_MediaController extends Zend_Rest_Controller $this->getResponse() ->setHttpResponseCode(200) - ->appendBody(json_encode($this->sanitize($file))); + ->appendBody(json_encode($this->sanitizeResponse($file))); } else { $this->fileNotFoundResponse(); } @@ -98,7 +98,7 @@ class Rest_MediaController extends Zend_Rest_Controller $this->getResponse() ->setHttpResponseCode(201) - ->appendBody(json_encode($this->sanitize($file))); + ->appendBody(json_encode($this->sanitizeResponse($file))); } public function putAction() @@ -114,14 +114,13 @@ class Rest_MediaController extends Zend_Rest_Controller $file = CcFilesQuery::create()->findPk($id); if ($file) { - //TODO: Strip or sanitize the JSON output $file->fromArray($this->validateRequestData(json_decode($this->getRequest()->getRawBody(), true)), BasePeer::TYPE_FIELDNAME); $now = new DateTime("now", new DateTimeZone("UTC")); $file->setDbMtime($now); $file->save(); $this->getResponse() ->setHttpResponseCode(200) - ->appendBody(json_encode($this->sanitize($file))); + ->appendBody(json_encode($this->sanitizeResponse($file))); } else { $this->fileNotFoundResponse(); } @@ -267,7 +266,7 @@ class Rest_MediaController extends Zend_Rest_Controller * Strips out the private fields we do not want to send back in API responses */ //TODO: rename this function? - public function sanitize($file) + public function sanitizeResponse($file) { $response = $file->toArray(BasePeer::TYPE_FIELDNAME);