#!/bin/bash # Patch apllying tool template # v0.1.2 # (c) Copyright 2013. Magento Inc. # # DO NOT CHANGE ANY LINE IN THIS FILE. # 1. Check required system tools _check_installed_tools() { local missed="" until [ -z "$1" ]; do type -t $1 >/dev/null 2>/dev/null if (( $? != 0 )); then missed="$missed $1" fi shift done echo $missed } REQUIRED_UTILS='sed patch' MISSED_REQUIRED_TOOLS=`_check_installed_tools $REQUIRED_UTILS` if (( `echo $MISSED_REQUIRED_TOOLS | wc -w` > 0 )); then echo -e "Error! Some required system tools, that are utilized in this sh script, are not installed:\nTool(s) \"$MISSED_REQUIRED_TOOLS\" is(are) missed, please install it(them)." exit 1 fi # 2. Determine bin path for system tools CAT_BIN=`which cat` PATCH_BIN=`which patch` SED_BIN=`which sed` PWD_BIN=`which pwd` BASENAME_BIN=`which basename` BASE_NAME=`$BASENAME_BIN "$0"` # 3. Help menu if [ "$1" = "-?" -o "$1" = "-h" -o "$1" = "--help" ] then $CAT_BIN << EOFH Usage: sh $BASE_NAME [--help] [-R|--revert] [--list] Apply embedded patch. -R, --revert Revert previously applied embedded patch --list Show list of applied patches --help Show this help message EOFH exit 0 fi # 4. Get "revert" flag and "list applied patches" flag REVERT_FLAG= SHOW_APPLIED_LIST=0 if [ "$1" = "-R" -o "$1" = "--revert" ] then REVERT_FLAG=-R fi if [ "$1" = "--list" ] then SHOW_APPLIED_LIST=1 fi # 5. File pathes CURRENT_DIR=`$PWD_BIN`/ APP_ETC_DIR=`echo "$CURRENT_DIR""app/etc/"` APPLIED_PATCHES_LIST_FILE=`echo "$APP_ETC_DIR""applied.patches.list"` # 6. Show applied patches list if requested if [ "$SHOW_APPLIED_LIST" -eq 1 ] ; then echo -e "Applied/reverted patches list:" if [ -e "$APPLIED_PATCHES_LIST_FILE" ] then if [ ! -r "$APPLIED_PATCHES_LIST_FILE" ] then echo "ERROR: \"$APPLIED_PATCHES_LIST_FILE\" must be readable so applied patches list can be shown." exit 1 else $SED_BIN -n "/SUP-\|SUPEE-/p" $APPLIED_PATCHES_LIST_FILE fi else echo "" fi exit 0 fi # 7. Check applied patches track file and its directory _check_files() { if [ ! -e "$APP_ETC_DIR" ] then echo "ERROR: \"$APP_ETC_DIR\" must exist for proper tool work." exit 1 fi if [ ! -w "$APP_ETC_DIR" ] then echo "ERROR: \"$APP_ETC_DIR\" must be writeable for proper tool work." exit 1 fi if [ -e "$APPLIED_PATCHES_LIST_FILE" ] then if [ ! -w "$APPLIED_PATCHES_LIST_FILE" ] then echo "ERROR: \"$APPLIED_PATCHES_LIST_FILE\" must be writeable for proper tool work." exit 1 fi fi } _check_files # 8. Apply/revert patch # Note: there is no need to check files permissions for files to be patched. # "patch" tool will not modify any file if there is not enough permissions for all files to be modified. # Get start points for additional information and patch data SKIP_LINES=$((`$SED_BIN -n "/^__PATCHFILE_FOLLOWS__$/=" "$CURRENT_DIR""$BASE_NAME"` + 1)) ADDITIONAL_INFO_LINE=$(($SKIP_LINES - 3))p _apply_revert_patch() { DRY_RUN_FLAG= if [ "$1" = "dry-run" ] then DRY_RUN_FLAG=" --dry-run" echo "Checking if patch can be applied/reverted successfully..." fi PATCH_APPLY_REVERT_RESULT=`$SED_BIN -e '1,/^__PATCHFILE_FOLLOWS__$/d' "$CURRENT_DIR""$BASE_NAME" | $PATCH_BIN $DRY_RUN_FLAG $REVERT_FLAG -p0` PATCH_APPLY_REVERT_STATUS=$? if [ $PATCH_APPLY_REVERT_STATUS -eq 1 ] ; then echo -e "ERROR: Patch can't be applied/reverted successfully.\n\n$PATCH_APPLY_REVERT_RESULT" exit 1 fi if [ $PATCH_APPLY_REVERT_STATUS -eq 2 ] ; then echo -e "ERROR: Patch can't be applied/reverted successfully." exit 2 fi } REVERTED_PATCH_MARK= if [ -n "$REVERT_FLAG" ] then REVERTED_PATCH_MARK=" | REVERTED" fi _apply_revert_patch dry-run _apply_revert_patch # 9. Track patch applying result echo "Patch was applied/reverted successfully." ADDITIONAL_INFO=`$SED_BIN -n ""$ADDITIONAL_INFO_LINE"" "$CURRENT_DIR""$BASE_NAME"` APPLIED_REVERTED_ON_DATE=`date -u +"%F %T UTC"` APPLIED_REVERTED_PATCH_INFO=`echo -n "$APPLIED_REVERTED_ON_DATE"" | ""$ADDITIONAL_INFO""$REVERTED_PATCH_MARK"` echo -e "$APPLIED_REVERTED_PATCH_INFO\n$PATCH_APPLY_REVERT_RESULT\n\n" >> "$APPLIED_PATCHES_LIST_FILE" exit 0 PATCH_SUPEE-9767_CE_1.9.0.1_v2 | CE_1.9.0.1 | v2 | 6566db274beaeb9bcdb56a62e02cc2da532e618c | Thu Jun 22 04:30:03 2017 +0300 | v1.14.3.3..HEAD __PATCHFILE_FOLLOWS__ diff --git app/code/core/Mage/Admin/Model/Session.php app/code/core/Mage/Admin/Model/Session.php index 81dcf3b..e3ddc9f 100644 --- app/code/core/Mage/Admin/Model/Session.php +++ app/code/core/Mage/Admin/Model/Session.php @@ -138,6 +138,9 @@ class Mage_Admin_Model_Session extends Mage_Core_Model_Session_Abstract 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 app/code/core/Mage/Adminhtml/Block/Checkout/Formkey.php app/code/core/Mage/Adminhtml/Block/Checkout/Formkey.php new file mode 100644 index 0000000..c198491 --- /dev/null +++ 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 app/code/core/Mage/Adminhtml/Block/Notification/Symlink.php app/code/core/Mage/Adminhtml/Block/Notification/Symlink.php new file mode 100644 index 0000000..c1ad328 --- /dev/null +++ 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 app/code/core/Mage/Adminhtml/Model/Config/Data.php app/code/core/Mage/Adminhtml/Model/Config/Data.php index cde1166..9b9d154 100644 --- app/code/core/Mage/Adminhtml/Model/Config/Data.php +++ app/code/core/Mage/Adminhtml/Model/Config/Data.php @@ -167,6 +167,9 @@ class Mage_Adminhtml_Model_Config_Data extends Varien_Object 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 app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Symlink.php app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Symlink.php new file mode 100644 index 0000000..eb5fd7a --- /dev/null +++ app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Symlink.php @@ -0,0 +1,44 @@ +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 app/code/core/Mage/Checkout/controllers/MultishippingController.php app/code/core/Mage/Checkout/controllers/MultishippingController.php index a7e3728..3d687a7 100644 --- app/code/core/Mage/Checkout/controllers/MultishippingController.php +++ app/code/core/Mage/Checkout/controllers/MultishippingController.php @@ -233,6 +233,12 @@ class Mage_Checkout_MultishippingController extends Mage_Checkout_Controller_Act $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 @@ class Mage_Checkout_MultishippingController extends Mage_Checkout_Controller_Act */ 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 @@ class Mage_Checkout_MultishippingController extends Mage_Checkout_Controller_Act 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 app/code/core/Mage/Checkout/controllers/OnepageController.php app/code/core/Mage/Checkout/controllers/OnepageController.php index bf24410e..48868e6 100644 --- app/code/core/Mage/Checkout/controllers/OnepageController.php +++ app/code/core/Mage/Checkout/controllers/OnepageController.php @@ -350,6 +350,7 @@ class Mage_Checkout_OnepageController extends Mage_Checkout_Controller_Action if ($this->_expireAjax()) { return; } + if ($this->getRequest()->isPost()) { $method = $this->getRequest()->getPost('method'); $result = $this->getOnepage()->saveCheckoutMethod($method); @@ -365,6 +366,11 @@ class Mage_Checkout_OnepageController extends Mage_Checkout_Controller_Action 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 +413,11 @@ class Mage_Checkout_OnepageController extends Mage_Checkout_Controller_Action 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 +442,11 @@ class Mage_Checkout_OnepageController extends Mage_Checkout_Controller_Action 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 +481,11 @@ class Mage_Checkout_OnepageController extends Mage_Checkout_Controller_Action if ($this->_expireAjax()) { return; } + + if ($this->isFormkeyValidationOnCheckoutEnabled() && !$this->_validateFormKey()) { + return; + } + try { if (!$this->getRequest()->isPost()) { $this->_ajaxRedirectResponse(); diff --git app/code/core/Mage/Checkout/etc/system.xml app/code/core/Mage/Checkout/etc/system.xml index 61c6aca..290c6fc 100644 --- app/code/core/Mage/Checkout/etc/system.xml +++ 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 app/code/core/Mage/Cms/Model/Wysiwyg/Images/Storage.php app/code/core/Mage/Cms/Model/Wysiwyg/Images/Storage.php index 9a5d819..dbd7d35 100644 --- app/code/core/Mage/Cms/Model/Wysiwyg/Images/Storage.php +++ app/code/core/Mage/Cms/Model/Wysiwyg/Images/Storage.php @@ -282,6 +282,11 @@ class Mage_Cms_Model_Wysiwyg_Images_Storage extends Varien_Object } $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 app/code/core/Mage/Core/Controller/Front/Action.php app/code/core/Mage/Core/Controller/Front/Action.php index 748860b..60c39c5 100755 --- app/code/core/Mage/Core/Controller/Front/Action.php +++ app/code/core/Mage/Core/Controller/Front/Action.php @@ -39,6 +39,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 * * @var string @@ -159,4 +164,38 @@ class Mage_Core_Controller_Front_Action extends Mage_Core_Controller_Varien_Acti } 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 app/code/core/Mage/Core/Controller/Request/Http.php app/code/core/Mage/Core/Controller/Request/Http.php index 9e2100a..df3f8a3 100644 --- app/code/core/Mage/Core/Controller/Request/Http.php +++ app/code/core/Mage/Core/Controller/Request/Http.php @@ -148,7 +148,10 @@ class Mage_Core_Controller_Request_Http extends Zend_Controller_Request_Http $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 app/code/core/Mage/Core/Model/File/Validator/Image.php app/code/core/Mage/Core/Model/File/Validator/Image.php index 7f7b9d0..8618bca 100644 --- app/code/core/Mage/Core/Model/File/Validator/Image.php +++ app/code/core/Mage/Core/Model/File/Validator/Image.php @@ -87,10 +87,51 @@ class Mage_Core_Model_File_Validator_Image */ 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); + imagealphablending($img, false); + imagecopyresampled($img, $image, 0, 0, 0, 0, $imageWidth, $imageHeight, $imageWidth, $imageHeight); + imagesavealpha($img, true); + + switch ($fileType) { + case IMAGETYPE_GIF: + $transparencyIndex = imagecolortransparent($image); + if ($transparencyIndex >= 0) { + imagecolortransparent($img, $transparencyIndex); + for ($y = 0; $y < $imageHeight; ++$y) { + for ($x = 0; $x < $imageWidth; ++$x) { + if (((imagecolorat($img, $x, $y) >> 24) & 0x7F)) { + imagesetpixel($img, $x, $y, $transparencyIndex); + } + } + } + } + if (!imageistruecolor($image)) { + imagetruecolortopalette($img, false, imagecolorstotal($image)); + } + imagegif($img, $filePath); + break; + case IMAGETYPE_JPEG: + imagejpeg($img, $filePath, 100); + break; + case IMAGETYPE_PNG: + imagepng($img, $filePath); + break; + default: + break; + } + + 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 +146,4 @@ class Mage_Core_Model_File_Validator_Image { return in_array($nImageType, $this->_allowedImageTypes); } - } diff --git app/code/core/Mage/Core/etc/config.xml app/code/core/Mage/Core/etc/config.xml index 747d6f4..ab623c0 100644 --- app/code/core/Mage/Core/etc/config.xml +++ app/code/core/Mage/Core/etc/config.xml @@ -28,7 +28,7 @@ - 1.6.0.4 + 1.6.0.4.1.2 @@ -284,6 +284,9 @@ + + 1 + 0 localhost diff --git app/code/core/Mage/Core/etc/system.xml app/code/core/Mage/Core/etc/system.xml index df51dd1..36dbd10 100644 --- app/code/core/Mage/Core/etc/system.xml +++ app/code/core/Mage/Core/etc/system.xml @@ -41,6 +41,29 @@ + + + + + text + 0 + 1 + 0 + 0 + + + + select + adminhtml/system_config_source_yesno + 10 + 1 + 0 + 0 + + + + + - skin_jsjs/lib/jquery-1.10.2.min.js skin_jsjs/lib/modernizr.custom.min.js skin_jsjs/lib/selectivizr.js skin_jsjs/lib/matchMedia.js diff --git app/design/frontend/rwd/default/template/checkout/cart/shipping.phtml app/design/frontend/rwd/default/template/checkout/cart/shipping.phtml index 9c1ac06..6d5e87a 100644 --- app/design/frontend/rwd/default/template/checkout/cart/shipping.phtml +++ app/design/frontend/rwd/default/template/checkout/cart/shipping.phtml @@ -120,6 +120,7 @@ __('Update Total') ?> + getBlockHtml('formkey') ?>