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
+ 0localhost
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
- 25
- 1
- 1
- 1
-
-
-
- select
- adminhtml/system_config_source_yesno
- 10
- 1
- 1
- 1
- Warning! Enabling this feature is not recommended on production environments because it represents a potential security risk.
-
-
-
text
@@ -819,6 +799,25 @@
11
+
+
+ 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_offloaderheader7510
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.
+