diff --git a/app/code/core/Mage/Admin/Model/Session.php b/app/code/core/Mage/Admin/Model/Session.php index 6e414768cb8..40641d286bb 100644 --- a/app/code/core/Mage/Admin/Model/Session.php +++ b/app/code/core/Mage/Admin/Model/Session.php @@ -138,6 +138,9 @@ public function login($username, $password, $request = null) Mage::throwException(Mage::helper('adminhtml')->__('Invalid User Name or Password.')); } } catch (Mage_Core_Exception $e) { + $e->setMessage( + Mage::helper('adminhtml')->__('You did not sign in correctly or your account is temporarily disabled.') + ); Mage::dispatchEvent('admin_session_user_login_failed', array('user_name' => $username, 'exception' => $e)); if ($request && !$request->getParam('messageSent')) { diff --git a/app/code/core/Mage/Adminhtml/Block/Checkout/Formkey.php b/app/code/core/Mage/Adminhtml/Block/Checkout/Formkey.php new file mode 100644 index 00000000000..fb564d24919 --- /dev/null +++ b/app/code/core/Mage/Adminhtml/Block/Checkout/Formkey.php @@ -0,0 +1,52 @@ + Admin section + * + * @return string + */ + public function getSecurityAdminUrl() + { + return Mage::helper("adminhtml")->getUrl('adminhtml/system_config/edit/section/admin'); + } +} diff --git a/app/code/core/Mage/Adminhtml/Block/Notification/Symlink.php b/app/code/core/Mage/Adminhtml/Block/Notification/Symlink.php new file mode 100644 index 00000000000..9e8759096ae --- /dev/null +++ b/app/code/core/Mage/Adminhtml/Block/Notification/Symlink.php @@ -0,0 +1,36 @@ +_convertDate($value['from'], $value['locale']); + $value['from'] = $this->_convertDate($this->stripTags($value['from']), $value['locale']); } if (!empty($value['to'])) { $value['orig_to'] = $value['to']; - $value['to'] = $this->_convertDate($value['to'], $value['locale']); + $value['to'] = $this->_convertDate($this->stripTags($value['to']), $value['locale']); } } if (empty($value['from']) && empty($value['to'])) { diff --git a/app/code/core/Mage/Adminhtml/Model/Config/Data.php b/app/code/core/Mage/Adminhtml/Model/Config/Data.php index 437e257bb60..f1d066ae35b 100644 --- a/app/code/core/Mage/Adminhtml/Model/Config/Data.php +++ b/app/code/core/Mage/Adminhtml/Model/Config/Data.php @@ -167,6 +167,9 @@ public function save() if (is_object($fieldConfig)) { $configPath = (string)$fieldConfig->config_path; if (!empty($configPath) && strrpos($configPath, '/') > 0) { + if (!Mage::getSingleton('admin/session')->isAllowed($configPath)) { + Mage::throwException('Access denied.'); + } // Extend old data with specified section group $groupPath = substr($configPath, 0, strrpos($configPath, '/')); if (!isset($oldConfigAdditionalGroups[$groupPath])) { diff --git a/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Web/Secure/Offloaderheader.php b/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Web/Secure/Offloaderheader.php new file mode 100644 index 00000000000..4f58256f574 --- /dev/null +++ b/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Web/Secure/Offloaderheader.php @@ -0,0 +1,29 @@ +setAllowRenameFiles(true); $uploader->setFilesDispersion(true); + $uploader->addValidateCallback( + Mage_Core_Model_File_Validator_Image::NAME, + Mage::getModel('core/file_validator_image'), + 'validate' + ); $result = $uploader->save( Mage::getSingleton('catalog/product_media_config')->getBaseTmpMediaPath() ); diff --git a/app/code/core/Mage/Checkout/controllers/MultishippingController.php b/app/code/core/Mage/Checkout/controllers/MultishippingController.php index 9e8293fe6a8..71d3a5498d0 100644 --- a/app/code/core/Mage/Checkout/controllers/MultishippingController.php +++ b/app/code/core/Mage/Checkout/controllers/MultishippingController.php @@ -233,6 +233,12 @@ public function addressesPostAction() $this->_redirect('*/multishipping_address/newShipping'); return; } + + if ($this->isFormkeyValidationOnCheckoutEnabled() && !$this->_validateFormKey()) { + $this->_redirect('*/*/addresses'); + return; + } + try { if ($this->getRequest()->getParam('continue', false)) { $this->_getCheckout()->setCollectRatesFlag(true); @@ -353,6 +359,11 @@ public function backToShippingAction() */ public function shippingPostAction() { + if ($this->isFormkeyValidationOnCheckoutEnabled() && !$this->_validateFormKey()) { + $this->_redirect('*/*/shipping'); + return; + } + $shippingMethods = $this->getRequest()->getPost('shipping_method'); try { Mage::dispatchEvent( @@ -439,6 +450,11 @@ public function overviewAction() return $this; } + if ($this->isFormkeyValidationOnCheckoutEnabled() && !$this->_validateFormKey()) { + $this->_redirect('*/*/billing'); + return; + } + $this->_getState()->setActiveStep(Mage_Checkout_Model_Type_Multishipping_State::STEP_OVERVIEW); try { diff --git a/app/code/core/Mage/Checkout/controllers/OnepageController.php b/app/code/core/Mage/Checkout/controllers/OnepageController.php index 47fb32308d4..9b9f9ff669a 100644 --- a/app/code/core/Mage/Checkout/controllers/OnepageController.php +++ b/app/code/core/Mage/Checkout/controllers/OnepageController.php @@ -350,6 +350,11 @@ public function saveMethodAction() if ($this->_expireAjax()) { return; } + + if ($this->isFormkeyValidationOnCheckoutEnabled() && !$this->_validateFormKey()) { + return; + } + if ($this->getRequest()->isPost()) { $method = $this->getRequest()->getPost('method'); $result = $this->getOnepage()->saveCheckoutMethod($method); @@ -365,6 +370,11 @@ public function saveBillingAction() if ($this->_expireAjax()) { return; } + + if ($this->isFormkeyValidationOnCheckoutEnabled() && !$this->_validateFormKey()) { + return; + } + if ($this->getRequest()->isPost()) { $data = $this->getRequest()->getPost('billing', array()); $customerAddressId = $this->getRequest()->getPost('billing_address_id', false); @@ -407,6 +417,11 @@ public function saveShippingAction() if ($this->_expireAjax()) { return; } + + if ($this->isFormkeyValidationOnCheckoutEnabled() && !$this->_validateFormKey()) { + return; + } + if ($this->getRequest()->isPost()) { $data = $this->getRequest()->getPost('shipping', array()); $customerAddressId = $this->getRequest()->getPost('shipping_address_id', false); @@ -431,6 +446,11 @@ public function saveShippingMethodAction() if ($this->_expireAjax()) { return; } + + if ($this->isFormkeyValidationOnCheckoutEnabled() && !$this->_validateFormKey()) { + return; + } + if ($this->getRequest()->isPost()) { $data = $this->getRequest()->getPost('shipping_method', ''); $result = $this->getOnepage()->saveShippingMethod($data); @@ -465,6 +485,11 @@ public function savePaymentAction() if ($this->_expireAjax()) { return; } + + if ($this->isFormkeyValidationOnCheckoutEnabled() && !$this->_validateFormKey()) { + return; + } + try { if (!$this->getRequest()->isPost()) { $this->_ajaxRedirectResponse(); diff --git a/app/code/core/Mage/Checkout/etc/system.xml b/app/code/core/Mage/Checkout/etc/system.xml index e6af3a9dbfc..1e4bd941437 100644 --- a/app/code/core/Mage/Checkout/etc/system.xml +++ b/app/code/core/Mage/Checkout/etc/system.xml @@ -232,5 +232,23 @@ + + + + + + + select + adminhtml/system_config_source_yesno + 4 + Important! Enabling this option means + that your custom templates used in checkout process contain form_key output. + Otherwise checkout may not work.]]> + 1 + + + + + diff --git a/app/code/core/Mage/Cms/Model/Wysiwyg/Images/Storage.php b/app/code/core/Mage/Cms/Model/Wysiwyg/Images/Storage.php index 810d3a5a00b..394dfa2ed9c 100644 --- a/app/code/core/Mage/Cms/Model/Wysiwyg/Images/Storage.php +++ b/app/code/core/Mage/Cms/Model/Wysiwyg/Images/Storage.php @@ -282,6 +282,11 @@ public function uploadFile($targetPath, $type = null) } $uploader->setAllowRenameFiles(true); $uploader->setFilesDispersion(false); + $uploader->addValidateCallback( + Mage_Core_Model_File_Validator_Image::NAME, + Mage::getModel('core/file_validator_image'), + 'validate' + ); $result = $uploader->save($targetPath); if (!$result) { diff --git a/app/code/core/Mage/Core/Controller/Front/Action.php b/app/code/core/Mage/Core/Controller/Front/Action.php index 5494c1a5406..045acb648ee 100755 --- a/app/code/core/Mage/Core/Controller/Front/Action.php +++ b/app/code/core/Mage/Core/Controller/Front/Action.php @@ -38,6 +38,11 @@ class Mage_Core_Controller_Front_Action extends Mage_Core_Controller_Varien_Acti */ const SESSION_NAMESPACE = 'frontend'; + /** + * Add secret key to url config path + */ + const XML_CSRF_USE_FLAG_CONFIG_PATH = 'system/csrf/use_form_key'; + /** * Currently used area * @@ -159,4 +164,38 @@ protected function _prepareDownloadResponse($fileName, $content, $contentType = } return $this; } + + /** + * Validate Form Key + * + * @return bool + */ + protected function _validateFormKey() + { + $validated = true; + if ($this->_isFormKeyEnabled()) { + $validated = parent::_validateFormKey(); + } + return $validated; + } + + /** + * Check if form key validation is enabled. + * + * @return bool + */ + protected function _isFormKeyEnabled() + { + return Mage::getStoreConfigFlag(self::XML_CSRF_USE_FLAG_CONFIG_PATH); + } + + /** + * Check if form_key validation enabled on checkout process + * + * @return bool + */ + protected function isFormkeyValidationOnCheckoutEnabled() + { + return Mage::getStoreConfigFlag('admin/security/validate_formkey_checkout'); + } } diff --git a/app/code/core/Mage/Core/Controller/Request/Http.php b/app/code/core/Mage/Core/Controller/Request/Http.php index 1735c55dd4d..83f6802abc3 100644 --- a/app/code/core/Mage/Core/Controller/Request/Http.php +++ b/app/code/core/Mage/Core/Controller/Request/Http.php @@ -148,7 +148,10 @@ public function setPathInfo($pathInfo = null) $baseUrl = $this->getBaseUrl(); $pathInfo = substr($requestUri, strlen($baseUrl)); - if ((null !== $baseUrl) && (false === $pathInfo)) { + if ($baseUrl && $pathInfo && (0 !== stripos($pathInfo, '/'))) { + $pathInfo = ''; + $this->setActionName('noRoute'); + } elseif ((null !== $baseUrl) && (false === $pathInfo)) { $pathInfo = ''; } elseif (null === $baseUrl) { $pathInfo = $requestUri; diff --git a/app/code/core/Mage/Core/Model/File/Validator/Image.php b/app/code/core/Mage/Core/Model/File/Validator/Image.php index 7f7b9d045d9..cbbcbb1c80c 100644 --- a/app/code/core/Mage/Core/Model/File/Validator/Image.php +++ b/app/code/core/Mage/Core/Model/File/Validator/Image.php @@ -87,10 +87,33 @@ public function setAllowedImageTypes(array $imageFileExtensions = array()) */ public function validate($filePath) { - $fileInfo = getimagesize($filePath); - if (is_array($fileInfo) and isset($fileInfo[2])) { - if ($this->isImageType($fileInfo[2])) { - return null; + list($imageWidth, $imageHeight, $fileType) = getimagesize($filePath); + if ($fileType) { + if ($this->isImageType($fileType)) { + //replace tmp image with re-sampled copy to exclude images with malicious data + $image = imagecreatefromstring(file_get_contents($filePath)); + if ($image !== false) { + $img = imagecreatetruecolor($imageWidth, $imageHeight); + imagecopyresampled($img, $image, 0, 0, 0, 0, $imageWidth, $imageHeight, $imageWidth, $imageHeight); + switch ($fileType) { + case IMAGETYPE_GIF: + imagegif($img, $filePath); + break; + case IMAGETYPE_JPEG: + imagejpeg($img, $filePath, 100); + break; + case IMAGETYPE_PNG: + imagepng($img, $filePath); + break; + default: + return; + } + imagedestroy($img); + imagedestroy($image); + return null; + } else { + throw Mage::exception('Mage_Core', Mage::helper('core')->__('Invalid image.')); + } } } throw Mage::exception('Mage_Core', Mage::helper('core')->__('Invalid MIME type.')); @@ -105,5 +128,4 @@ protected function isImageType($nImageType) { return in_array($nImageType, $this->_allowedImageTypes); } - } diff --git a/app/code/core/Mage/Core/etc/config.xml b/app/code/core/Mage/Core/etc/config.xml index 8eca50de807..39ce72eebb4 100644 --- a/app/code/core/Mage/Core/etc/config.xml +++ b/app/code/core/Mage/Core/etc/config.xml @@ -274,6 +274,9 @@ + + 1 + 0 localhost diff --git a/app/code/core/Mage/Core/etc/system.xml b/app/code/core/Mage/Core/etc/system.xml index 94fdab21c28..b2f22e2b123 100644 --- a/app/code/core/Mage/Core/etc/system.xml +++ b/app/code/core/Mage/Core/etc/system.xml @@ -529,26 +529,6 @@ - text @@ -819,6 +799,25 @@ 1 1 + + + text + 0 + 1 + 1 + 1 + + + + select + adminhtml/system_config_source_yesno + 10 + 1 + 1 + 1 + + + text @@ -1336,6 +1335,7 @@ text + adminhtml/system_config_backend_web_secure_offloaderheader 75 1 0 diff --git a/app/code/core/Mage/Customer/Model/Session.php b/app/code/core/Mage/Customer/Model/Session.php index 266b06e537b..9918d2157bc 100644 --- a/app/code/core/Mage/Customer/Model/Session.php +++ b/app/code/core/Mage/Customer/Model/Session.php @@ -222,6 +222,8 @@ public function login($username, $password) public function setCustomerAsLoggedIn($customer) { $this->setCustomer($customer); + $this->renewSession(); + Mage::getSingleton('core/session')->renewFormKey(); Mage::dispatchEvent('customer_login', array('customer'=>$customer)); return $this; } @@ -307,6 +309,7 @@ protected function _logout() $this->setId(null); $this->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID); $this->getCookie()->delete($this->getSessionName()); + Mage::getSingleton('core/session')->renewFormKey(); return $this; } diff --git a/app/code/core/Mage/Dataflow/Model/Convert/Adapter/Zend/Cache.php b/app/code/core/Mage/Dataflow/Model/Convert/Adapter/Zend/Cache.php index 66e03d2486a..88ec799e9c0 100644 --- a/app/code/core/Mage/Dataflow/Model/Convert/Adapter/Zend/Cache.php +++ b/app/code/core/Mage/Dataflow/Model/Convert/Adapter/Zend/Cache.php @@ -40,6 +40,9 @@ public function getResource() if (!$this->_resource) { $this->_resource = Zend_Cache::factory($this->getVar('frontend', 'Core'), $this->getVar('backend', 'File')); } + if ($this->_resource->getBackend() instanceof Zend_Cache_Backend_Static) { + throw new Exception(Mage::helper('dataflow')->__('Backend name "Static" not supported.')); + } return $this->_resource; } diff --git a/app/code/core/Mage/Dataflow/Model/Convert/Container/Abstract.php b/app/code/core/Mage/Dataflow/Model/Convert/Container/Abstract.php index 52f86c09953..d32cd5ab3c1 100644 --- a/app/code/core/Mage/Dataflow/Model/Convert/Container/Abstract.php +++ b/app/code/core/Mage/Dataflow/Model/Convert/Container/Abstract.php @@ -47,6 +47,18 @@ abstract class Mage_Dataflow_Model_Convert_Container_Abstract protected $_position; + /** + * Detect serialization of data + * + * @param mixed $data + * @return bool + */ + protected function isSerialized($data) + { + $pattern = '/^a:\d+:\{(i:\d+;|s:\d+:\".+\";|N;|O:\d+:\"\w+\":\d+:\{\w:\d+:)+|^O:\d+:\"\w+\":\d+:\{s:\d+:\"/'; + return (is_string($data) && preg_match($pattern, $data)); + } + public function getVar($key, $default=null) { if (!isset($this->_vars[$key]) || (!is_array($this->_vars[$key]) && strlen($this->_vars[$key]) == 0)) { @@ -102,13 +114,45 @@ public function getData() public function setData($data) { - if ($this->getProfile()) { - $this->getProfile()->getContainer()->setData($data); + if ($this->validateDataSerialized($data)) { + if ($this->getProfile()) { + $this->getProfile()->getContainer()->setData($data); + } + + $this->_data = $data; } - $this->_data = $data; + return $this; } + /** + * Validate serialized data + * + * @param mixed $data + * @return bool + */ + public function validateDataSerialized($data = null) + { + if (is_null($data)) { + $data = $this->getData(); + } + + $result = true; + if ($this->isSerialized($data)) { + try { + $dataArray = Mage::helper('core/unserializeArray')->unserialize($data); + } catch (Exception $e) { + $result = false; + $this->addException( + "Invalid data, expecting serialized array.", + Mage_Dataflow_Model_Convert_Exception::FATAL + ); + } + } + + return $result; + } + public function validateDataString($data=null) { if (is_null($data)) { @@ -140,7 +184,10 @@ public function validateDataGrid($data=null) if (count($data)==0) { return true; } - $this->addException("Invalid data type, expecting 2D grid array.", Mage_Dataflow_Model_Convert_Exception::FATAL); + $this->addException( + "Invalid data type, expecting 2D grid array.", + Mage_Dataflow_Model_Convert_Exception::FATAL + ); } return true; } diff --git a/app/code/core/Mage/Dataflow/Model/Convert/Parser/Csv.php b/app/code/core/Mage/Dataflow/Model/Convert/Parser/Csv.php index 312df4ee514..66c45eedfba 100644 --- a/app/code/core/Mage/Dataflow/Model/Convert/Parser/Csv.php +++ b/app/code/core/Mage/Dataflow/Model/Convert/Parser/Csv.php @@ -62,13 +62,15 @@ public function parse() $adapter = Mage::getModel($adapterName); } catch (Exception $e) { - $message = Mage::helper('dataflow')->__('Declared adapter %s was not found.', $adapterName); + $message = Mage::helper('dataflow') + ->__('Declared adapter %s was not found.', $adapterName); $this->addException($message, Mage_Dataflow_Model_Convert_Exception::FATAL); return $this; } if (!method_exists($adapter, $adapterMethod)) { - $message = Mage::helper('dataflow')->__('Method "%s" not defined in adapter %s.', $adapterMethod, $adapterName); + $message = Mage::helper('dataflow') + ->__('Method "%s" not defined in adapter %s.', $adapterMethod, $adapterName); $this->addException($message, Mage_Dataflow_Model_Convert_Exception::FATAL); return $this; } @@ -77,8 +79,8 @@ public function parse() $batchIoAdapter = $this->getBatchModel()->getIoAdapter(); if (Mage::app()->getRequest()->getParam('files')) { - $file = Mage::app()->getConfig()->getTempVarDir().'/import/' - . urldecode(Mage::app()->getRequest()->getParam('files')); + $file = Mage::app()->getConfig()->getTempVarDir() . '/import/' + . str_replace('../', '', urldecode(Mage::app()->getRequest()->getParam('files'))); $this->_copy($file); } diff --git a/app/code/core/Mage/Dataflow/Model/Convert/Parser/Xml/Excel.php b/app/code/core/Mage/Dataflow/Model/Convert/Parser/Xml/Excel.php index d25bbf19c6f..57e26c0eb40 100644 --- a/app/code/core/Mage/Dataflow/Model/Convert/Parser/Xml/Excel.php +++ b/app/code/core/Mage/Dataflow/Model/Convert/Parser/Xml/Excel.php @@ -69,7 +69,8 @@ public function parse() } if (!method_exists($adapter, $adapterMethod)) { - $message = Mage::helper('dataflow')->__('Method "%s" was not defined in adapter %s.', $adapterMethod, $adapterName); + $message = Mage::helper('dataflow') + ->__('Method "%s" was not defined in adapter %s.', $adapterMethod, $adapterName); $this->addException($message, Mage_Dataflow_Model_Convert_Exception::FATAL); return $this; } @@ -78,8 +79,8 @@ public function parse() $batchIoAdapter = $this->getBatchModel()->getIoAdapter(); if (Mage::app()->getRequest()->getParam('files')) { - $file = Mage::app()->getConfig()->getTempVarDir().'/import/' - . urldecode(Mage::app()->getRequest()->getParam('files')); + $file = Mage::app()->getConfig()->getTempVarDir() . '/import/' + . str_replace('../', '', urldecode(Mage::app()->getRequest()->getParam('files'))); $this->_copy($file); } diff --git a/app/code/core/Mage/ImportExport/Model/Import/Uploader.php b/app/code/core/Mage/ImportExport/Model/Import/Uploader.php index b4208845b5a..898cbc8877b 100644 --- a/app/code/core/Mage/ImportExport/Model/Import/Uploader.php +++ b/app/code/core/Mage/ImportExport/Model/Import/Uploader.php @@ -61,6 +61,11 @@ public function init() $this->setAllowedExtensions(array_keys($this->_allowedMimeTypes)); $this->addValidateCallback('catalog_product_image', Mage::helper('catalog/image'), 'validateUploadFile'); + $this->addValidateCallback( + Mage_Core_Model_File_Validator_Image::NAME, + Mage::getModel('core/file_validator_image'), + 'validate' + ); $this->_uploadType = self::SINGLE_STYLE; } diff --git a/app/code/core/Mage/Payment/Model/Method/Cc.php b/app/code/core/Mage/Payment/Model/Method/Cc.php index ccf240ee344..7b6f3b92d42 100644 --- a/app/code/core/Mage/Payment/Model/Method/Cc.php +++ b/app/code/core/Mage/Payment/Model/Method/Cc.php @@ -123,7 +123,7 @@ public function validate() // Visa 'VI' => '/^4[0-9]{12}([0-9]{3})?$/', // Master Card - 'MC' => '/^5[1-5][0-9]{14}$/', + 'MC' => '/^(5[1-5][0-9]{14}|2(22[1-9][0-9]{12}|2[3-9][0-9]{13}|[3-6][0-9]{14}|7[0-1][0-9]{13}|720[0-9]{12}))$/', // American Express 'AE' => '/^3[47][0-9]{13}$/', // Discovery diff --git a/app/code/core/Mage/Paypal/Model/Ipn.php b/app/code/core/Mage/Paypal/Model/Ipn.php index b4e794d157e..f6e85beee69 100644 --- a/app/code/core/Mage/Paypal/Model/Ipn.php +++ b/app/code/core/Mage/Paypal/Model/Ipn.php @@ -36,6 +36,20 @@ class Mage_Paypal_Model_Ipn */ const DEFAULT_LOG_FILE = 'paypal_unknown_ipn.log'; + /** + * Default postback endpoint URL. + * + * @var string + */ + const DEFAULT_POSTBACK_URL = 'https://ipnpb.paypal.com/cgi-bin/webscr'; + + /** + * Sandbox postback endpoint URL. + * + * @var string + */ + const SANDBOX_POSTBACK_URL = 'https://ipnpb.sandbox.paypal.com/cgi-bin/webscr'; + /* * @param Mage_Sales_Model_Order */ @@ -130,6 +144,8 @@ public function processIpnRequest(array $request, Zend_Http_Client_Adapter_Inter */ protected function _postBack(Zend_Http_Client_Adapter_Interface $httpAdapter) { + $url = $this->_getPostbackUrl(); + $sReq = ''; foreach ($this->_request as $k => $v) { $sReq .= '&'.$k.'='.urlencode($v); @@ -137,10 +153,10 @@ protected function _postBack(Zend_Http_Client_Adapter_Interface $httpAdapter) $sReq .= "&cmd=_notify-validate"; $sReq = substr($sReq, 1); $this->_debugData['postback'] = $sReq; - $this->_debugData['postback_to'] = $this->_config->getPaypalUrl(); + $this->_debugData['postback_to'] = $url; $httpAdapter->setConfig(array('verifypeer' => $this->_config->verifyPeer)); - $httpAdapter->write(Zend_Http_Client::POST, $this->_config->getPaypalUrl(), '1.1', array( + $httpAdapter->write(Zend_Http_Client::POST, $url, '1.1', array( 'Connection: close', ), $sReq); try { @@ -159,6 +175,16 @@ protected function _postBack(Zend_Http_Client_Adapter_Interface $httpAdapter) unset($this->_debugData['postback'], $this->_debugData['postback_result']); } + /** + * Get postback endpoint URL. + * + * @return string + */ + protected function _getPostbackUrl() + { + return $this->_config->sandboxFlag ? self::SANDBOX_POSTBACK_URL : self::DEFAULT_POSTBACK_URL; + } + /** * Load and validate order, instantiate proper configuration * diff --git a/app/code/core/Mage/Sales/Model/Quote/Item.php b/app/code/core/Mage/Sales/Model/Quote/Item.php index bea33090820..03dee1cce6a 100644 --- a/app/code/core/Mage/Sales/Model/Quote/Item.php +++ b/app/code/core/Mage/Sales/Model/Quote/Item.php @@ -498,8 +498,9 @@ public function compare($item) /** @var Unserialize_Parser $parser */ $parser = Mage::helper('core/unserializeArray'); - $_itemOptionValue = $parser->unserialize($itemOptionValue); - $_optionValue = $parser->unserialize($optionValue); + $_itemOptionValue = + is_numeric($itemOptionValue) ? $itemOptionValue : $parser->unserialize($itemOptionValue); + $_optionValue = is_numeric($optionValue) ? $optionValue : $parser->unserialize($optionValue); if (is_array($_itemOptionValue) && is_array($_optionValue)) { $itemOptionValue = $_itemOptionValue; diff --git a/app/code/core/Mage/Tax/Model/Calculation.php b/app/code/core/Mage/Tax/Model/Calculation.php index 38355c4c744..9a4f8b8e1fb 100644 --- a/app/code/core/Mage/Tax/Model/Calculation.php +++ b/app/code/core/Mage/Tax/Model/Calculation.php @@ -553,6 +553,17 @@ public function getAppliedRates($request) return $this->_rateCalculationProcess[$cacheKey]; } + /** + * Get rate ids applicable for some address + * + * @param Varien_Object $request + * @return array + */ + public function getApplicableRateIds($request) + { + return $this->_getResource()->getApplicableRateIds($request); + } + /** * Get the calculation process * diff --git a/app/code/core/Mage/Tax/Model/Resource/Calculation.php b/app/code/core/Mage/Tax/Model/Resource/Calculation.php index bb447725501..3e0e30f8678 100755 --- a/app/code/core/Mage/Tax/Model/Resource/Calculation.php +++ b/app/code/core/Mage/Tax/Model/Resource/Calculation.php @@ -361,6 +361,35 @@ protected function _getRates($request) return $this->_ratesCache[$cacheKey]; } + /** + * Get rate ids applicable for some address + * + * @param Varien_Object $request + * @return array + */ + function getApplicableRateIds($request) + { + $countryId = $request->getCountryId(); + $regionId = $request->getRegionId(); + $postcode = $request->getPostcode(); + + $select = $this->_getReadAdapter()->select() + ->from(array('rate' => $this->getTable('tax/tax_calculation_rate')), array('tax_calculation_rate_id')) + ->where('rate.tax_country_id = ?', $countryId) + ->where("rate.tax_region_id IN(?)", array(0, (int)$regionId)); + + $expr = $this->_getWriteAdapter()->getCheckSql( + 'zip_is_range is NULL', + $this->_getWriteAdapter()->quoteInto( + "rate.tax_postcode IS NULL OR rate.tax_postcode IN('*', '', ?)", + $this->_createSearchPostCodeTemplates($postcode) + ), + $this->_getWriteAdapter()->quoteInto('? BETWEEN rate.zip_from AND rate.zip_to', $postcode) + ); + $select->where($expr); + return $this->_getReadAdapter()->fetchCol($select); + } + /** * Calculate rate * diff --git a/app/code/core/Mage/Widget/Model/Widget/Instance.php b/app/code/core/Mage/Widget/Model/Widget/Instance.php index f070c6d1035..faddd1647ff 100644 --- a/app/code/core/Mage/Widget/Model/Widget/Instance.php +++ b/app/code/core/Mage/Widget/Model/Widget/Instance.php @@ -347,7 +347,11 @@ public function getStoreIds() public function getWidgetParameters() { if (is_string($this->getData('widget_parameters'))) { - return unserialize($this->getData('widget_parameters')); + try { + return Mage::helper('core/unserializeArray')->unserialize($this->getData('widget_parameters')); + } catch (Exception $e) { + Mage::logException($e); + } } return (is_array($this->getData('widget_parameters'))) ? $this->getData('widget_parameters') : array(); } diff --git a/app/code/core/Mage/XmlConnect/Helper/Image.php b/app/code/core/Mage/XmlConnect/Helper/Image.php index c3d1d920094..573be065bd9 100644 --- a/app/code/core/Mage/XmlConnect/Helper/Image.php +++ b/app/code/core/Mage/XmlConnect/Helper/Image.php @@ -100,6 +100,11 @@ public function handleUpload($field) $uploader = Mage::getModel('core/file_uploader', $field); $uploader->setAllowedExtensions(array('jpg', 'jpeg', 'gif', 'png')); $uploader->setAllowRenameFiles(true); + $uploader->addValidateCallback( + Mage_Core_Model_File_Validator_Image::NAME, + Mage::getModel('core/file_validator_image'), + 'validate' + ); $uploader->save($uploadDir); $uploadedFilename = $uploader->getUploadedFileName(); $uploadedFilename = $this->_getResizedFilename($field, $uploadedFilename, true); diff --git a/app/code/core/Mage/XmlConnect/controllers/Adminhtml/MobileController.php b/app/code/core/Mage/XmlConnect/controllers/Adminhtml/MobileController.php index 5532c878d54..0f293b363ff 100644 --- a/app/code/core/Mage/XmlConnect/controllers/Adminhtml/MobileController.php +++ b/app/code/core/Mage/XmlConnect/controllers/Adminhtml/MobileController.php @@ -567,7 +567,7 @@ public function deleteThemeAction() $result = $themesHelper->deleteTheme($themeId); if ($result) { $response = array( - 'message' => $this->__('Theme has been delete.'), + 'message' => $this->__('Theme has been deleted.'), 'themes' => $themesHelper->getAllThemesArray(true), 'themeSelector' => $themesHelper->getThemesSelector(), 'selectedTheme' => $themesHelper->getDefaultThemeName() @@ -1393,6 +1393,11 @@ public function uploadImagesAction() /** @var $uploader Mage_Core_Model_File_Uploader */ $uploader = Mage::getModel('core/file_uploader', $imageModel->getImageType()); $uploader->setAllowRenameFiles(true)->setAllowedExtensions(array('jpg', 'jpeg', 'gif', 'png')); + $uploader->addValidateCallback( + Mage_Core_Model_File_Validator_Image::NAME, + Mage::getModel('core/file_validator_image'), + 'validate' + ); $result = $uploader->save(Mage_XmlConnect_Model_Images::getBasePath(), $newFileName); $result['thumbnail'] = Mage::getModel('xmlconnect/images')->getCustomSizeImageUrl( $result['file'], diff --git a/app/design/adminhtml/default/default/layout/main.xml b/app/design/adminhtml/default/default/layout/main.xml index 566b1c5b0b6..e2409c14481 100644 --- a/app/design/adminhtml/default/default/layout/main.xml +++ b/app/design/adminhtml/default/default/layout/main.xml @@ -119,7 +119,8 @@ Default layout, loads most of the pages - + + diff --git a/app/design/adminhtml/default/default/template/notification/formkey.phtml b/app/design/adminhtml/default/default/template/notification/formkey.phtml new file mode 100644 index 00000000000..ec99a74f76e --- /dev/null +++ b/app/design/adminhtml/default/default/template/notification/formkey.phtml @@ -0,0 +1,38 @@ + +canShow()): ?> +
+ Important: + Formkey validation on checkout disabled. This may expose security risks. + We strongly recommend to Enable Form Key Validation On Checkout in + Admin / Security Section, + for protect your own checkout process. +
+ diff --git a/app/design/adminhtml/default/default/template/notification/symlink.phtml b/app/design/adminhtml/default/default/template/notification/symlink.phtml new file mode 100644 index 00000000000..2a609011390 --- /dev/null +++ b/app/design/adminhtml/default/default/template/notification/symlink.phtml @@ -0,0 +1,34 @@ + +isSymlinkEnabled()): ?> +
+ helper('adminhtml')->__('Symlinks are enabled. This may expose security risks. We strongly recommend to disable them.')?> +
+ diff --git a/app/design/adminhtml/default/default/template/page/head.phtml b/app/design/adminhtml/default/default/template/page/head.phtml index ef6371f7589..3f944dc484a 100644 --- a/app/design/adminhtml/default/default/template/page/head.phtml +++ b/app/design/adminhtml/default/default/template/page/head.phtml @@ -7,7 +7,7 @@ var BLANK_URL = 'getJsUrl() ?>blank.html'; var BLANK_IMG = 'getJsUrl() ?>spacer.gif'; var BASE_URL = 'getUrl('*') ?>'; - var SKIN_URL = 'getSkinUrl() ?>'; + var SKIN_URL = 'jsQuoteEscape($this->getSkinUrl()) ?>'; var FORM_KEY = 'getFormKey() ?>'; diff --git a/app/design/frontend/base/default/template/checkout/cart/shipping.phtml b/app/design/frontend/base/default/template/checkout/cart/shipping.phtml index 926626229e9..43f29a0e66c 100644 --- a/app/design/frontend/base/default/template/checkout/cart/shipping.phtml +++ b/app/design/frontend/base/default/template/checkout/cart/shipping.phtml @@ -109,6 +109,7 @@
+ getBlockHtml('formkey') ?>