A new security patch is out for Magento 1, addressing 25 APPSEC issues

https://magento.com/security/patches/supee-10752

What common issues do you have to watch out for when applying this patch?

SUPEE-10752, Magento Commerce 1.14.3.9 and Open Source 1.9.3.9 contain multiple security enhancements that help close authenticated Admin user remote code execution (RCE), cross-site request forgery (CSRF) and other vulnerabilities.

Information on all the changes in 1.14.3.9 and 1.9.3.9 releases is available in the Magento Commerce and Magento Open Source release notes.

Patches and upgrades are available for the following Magento versions:

Magento Commerce 1.9.0.0-1.14.3.9: SUPEE-10752 or upgrade to Magento Commerce 1.14.3.9.

Magento Open Source 1.5.0.0-1.9.3.9: SUPEE-10752 or upgrade to Magento Open Source 1.9.3.9.

14 Answers 14

As Mentioned by Official Docs By Magento:

Conflicts during installation of the patch SUPEE-10752 are caused most often by having version 1 of the previous patch installed (SUPEE-10570v1).

Please make sure to remove SUPEE-10570v1 and install SUPEE-10570v2 prior to installation of new SUPEE-10752.

The below files are changed/created after apply patch

app/code/core/Mage/Admin/Model/User.php
app/code/core/Mage/Adminhtml/Block/Catalog/Product/Composite/Fieldset/Options.php
app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Options/Option.php
app/code/core/Mage/Adminhtml/Block/Widget/Grid/Column/Filter/Datetime.php
app/code/core/Mage/Adminhtml/Model/LayoutUpdate/Validator.php
app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php
app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php
app/code/core/Mage/Adminhtml/controllers/Cms/Wysiwyg/ImagesController.php
app/code/core/Mage/Adminhtml/controllers/Cms/WysiwygController.php
app/code/core/Mage/Adminhtml/controllers/CustomerController.php
app/code/core/Mage/Adminhtml/controllers/System/StoreController.php
app/code/core/Mage/Catalog/Model/Product.php
app/code/core/Mage/Catalog/Model/Resource/Category/Tree.php
app/code/core/Mage/Checkout/Model/Api/Resource/Customer.php
app/code/core/Mage/Checkout/Model/Type/Onepage.php
app/code/core/Mage/Checkout/controllers/CartController.php
app/code/core/Mage/Core/Helper/Http.php
app/code/core/Mage/Core/Model/Session/Abstract/Varien.php
app/code/core/Mage/Customer/Helper/Data.php
app/code/core/Mage/Customer/Model/Resource/Customer.php
app/code/core/Mage/Customer/controllers/AccountController.php
app/code/core/Mage/Log/Model/Visitor.php
app/code/core/Mage/Usa/Helper/Data.php
app/code/core/Mage/Usa/Model/Shipping/Carrier/Abstract/Backend/Abstract.php
app/code/core/Mage/Usa/Model/Shipping/Carrier/Ups/Backend/Freemethod.php
app/code/core/Mage/Usa/Model/Shipping/Carrier/Ups/Backend/OriginShipment.php
app/code/core/Mage/Usa/Model/Shipping/Carrier/Ups/Backend/Type.php
app/code/core/Mage/Usa/etc/system.xml
app/code/core/Zend/Filter/PregReplace.php
app/code/core/Zend/Validate/EmailAddress.php
app/design/adminhtml/default/default/template/bundle/product/edit/bundle/option.phtml

app/design/adminhtml/default/default/template/system/shipping/ups.phtml
app/design/frontend/base/default/template/downloadable/catalog/product/links.phtml
app/design/frontend/base/default/template/downloadable/checkout/cart/item/default.phtml
app/design/frontend/base/default/template/downloadable/checkout/onepage/review/item.phtml
app/design/frontend/base/default/template/downloadable/sales/order/items/renderer/downloadable.phtml
app/design/frontend/rwd/default/template/downloadable/checkout/cart/item/default.phtml
app/design/frontend/rwd/default/template/downloadable/checkout/onepage/review/item.phtml
app/design/frontend/rwd/default/template/downloadable/sales/order/items/renderer/downloadable.phtml
app/locale/en_US/Mage_Catalog.csv
app/locale/en_US/Mage_Usa.csv
cron.php
js/tiny_mce/plugins/media/.htaccess
lib/Varien/Image/Adapter/Gd2.php

For EE Edition the below files are added other than CE

app/code/core/Enterprise/CatalogEvent/Block/Adminhtml/Event/Grid.php
app/code/core/Enterprise/GiftRegistry/Block/Adminhtml/Giftregistry/Edit/Attribute/Attribute.php
app/code/core/Enterprise/GiftRegistry/Model/Attribute/Processor.php
app/code/core/Enterprise/Invitation/Block/Adminhtml/Invitation/Grid.php
app/code/core/Enterprise/Logging/Block/Adminhtml/Details/Renderer/Diff.php
app/code/core/Enterprise/Reward/Block/Adminhtml/Customer/Edit/Tab/Reward/History/Grid/Column/Renderer/Reason.php
app/code/core/Enterprise/TargetRule/Model/Rule.php
app/code/core/Enterprise/TargetRule/controllers/Adminhtml/TargetruleController.php
app/design/adminhtml/default/default/template/enterprise/cms/page/revision/info.phtml

app/design/frontend/enterprise/default/template/cms/hierarchy/pagination.phtml
app/design/frontend/enterprise/iphone/template/downloadable/checkout/cart/item/default.phtml
app/design/frontend/enterprise/iphone/template/downloadable/checkout/onepage/review/item.phtml
app/design/frontend/rwd/enterprise/template/cms/hierarchy/pagination.phtml

app/code/core/Mage/Admin/Model/User.php

+            $sessionUser = $this->getSession()->getUser();
+            if ($sessionUser && $sessionUser->getId() == $this->getId()) {
+                $this->getSession()->setUserPasswordChanged(true);
+            }


+    /**
+     * @return Mage_Admin_Model_Session
+     */
+    protected function getSession()
+    {
+        return  Mage::getSingleton('admin/session');
+    }
+

app/code/core/Mage/Adminhtml/Block/Widget/Grid/Column/Filter/Datetime.php

                     $this->getLocale()->getDateTimeFormat(Mage_Core_Model_Locale::FORMAT_TYPE_SHORT)
                 );
             }
-            return $value;
+            return $this->escapeHtml($value);
         }

-        return parent::getEscapedValue($index);
+        return $this->escapeHtml(parent::getEscapedValue($index));
     }
-
 }

app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php

+            if (isset($data['general']['path'])) {
+                unset($data['general']['path']);
+            }

app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php

+                $product->validate();

app/code/core/Mage/Adminhtml/controllers/Cms/Wysiwyg/ImagesController.php

+            $this->getResponse()->setHeader('Content-type', $image->getMimeTypeWithOutFileType());

app/code/core/Mage/Adminhtml/controllers/Cms/WysiwygController.php

+        $this->getResponse()->setHeader('Content-type', $image->getMimeTypeWithOutFileType());

app/code/core/Mage/Adminhtml/controllers/CustomerController.php

+                    $customer->setPasswordCreatedAt(time());

app/code/core/Mage/Adminhtml/controllers/System/StoreController.php

+   /**
+     * Controller predispatch method
+     *
+     * @return Mage_Adminhtml_Controller_Action
+     */
+    public function preDispatch()
+    {
+        $this->_setForcedFormKeyActions(array('deleteWebsitePost', 'deleteGroupPost', 'deleteStorePost'));
+        return parent::preDispatch();
+    }

app/code/core/Mage/Catalog/Model/Product.php

+                        if (!empty($option['file_extension'])) {
+                            $fileExtension = $option['file_extension'];
+                            if (0 !== strcmp($fileExtension, Mage::helper('core')->removeTags($fileExtension))) {
+                                Mage::throwException(Mage::helper('catalog')->__('Invalid custom option(s).'));
+                            }
+                        }

app/code/core/Mage/Catalog/Model/Resource/Category/Tree.php

+            if (!preg_match("#^[0-9\/]+$#", $item['path'])) {
+                $item['path'] = '';
+            }

app/code/core/Mage/Checkout/Model/Api/Resource/Customer.php

+        $customer->setPasswordCreatedAt(time());

Anyone overrides onepage.php file please update the file.

app/code/core/Mage/Checkout/Model/Type/Onepage.php

  +        $passwordCreatedTime = $this->_checkoutSession->getData('_session_validator_data')['session_expire_timestamp']
    +            - Mage::getSingleton('core/cookie')->getLifetime();
    +        $customer->setPasswordCreatedAt($passwordCreatedTime);

For key validation added Please check your cart form have form key

app/code/core/Mage/Checkout/controllers/CartController.php

+        if (!$this->_validateFormKey()) {
+            $this->_redirect('*/*/');
+            return;
+        }
+

app/code/core/Mage/Core/Helper/Http.php

-                if ($this->_getRequest()->getServer($var, false)) {
+                if ($var != 'REMOTE_ADDR' && $this->_getRequest()->getServer($var, false)) {

+        if (strpos($this->_remoteAddr, ',') !== false) {
+            $ipList = explode(',', $this->_remoteAddr);
+            $this->_remoteAddr = trim(reset($ipList));
+        }
+

app/code/core/Mage/Core/Model/Session/Abstract/Varien.php

+    const VALIDATOR_PASSWORD_CREATE_TIMESTAMP   = 'password_create_timestamp';

+    /**
+     * Use password creation timestamp in validator key
+     *
+     * @return bool
+     */
+    public function useValidateSessionPasswordTimestamp()
+    {
+        return true;
+    }
+

+        if ($this->useValidateSessionPasswordTimestamp()
+            && isset($validatorData[self::VALIDATOR_PASSWORD_CREATE_TIMESTAMP])
+            && isset($sessionData[self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP])
+            && $validatorData[self::VALIDATOR_PASSWORD_CREATE_TIMESTAMP]
+            > $sessionData[self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP] - $this->getCookie()->getLifetime()
+        ) {
+            return false;
+        }

+        if (isset($this->_data['visitor_data']['customer_id'])) {
+            $parts[self::VALIDATOR_PASSWORD_CREATE_TIMESTAMP] =
+                Mage::helper('customer')->getPasswordTimestamp($this->_data['visitor_data']['customer_id']);
+        }
+

app/code/core/Mage/Customer/Helper/Data.php

+    /**
+     * Get customer password creation timestamp or customer account creation timestamp
+     *
+     * @param $customerId
+     * @return int
+     */
+    public function getPasswordTimestamp($customerId)
+    {
+        /** @var $customer Mage_Customer_Model_Customer */
+        $customer = Mage::getModel('customer/customer')
+            ->setWebsiteId(Mage::app()->getStore()->getWebsiteId())
+            ->load((int)$customerId);
+        $passwordCreatedAt = $customer->getPasswordCreatedAt();
+
+        return is_null($passwordCreatedAt) ? $customer->getCreatedAtTimestamp() : $passwordCreatedAt;
+    }
+

app/code/core/Mage/Customer/Model/Resource/Customer.php

-        $customer->setPassword($newPassword);
+        $customer->setPassword($newPassword)->setPasswordCreatedAt(time());
+        $this->saveAttribute($customer, 'password_created_at');
app/code/core/Mage/Customer/controllers/AccountController.php

+                $customer->setPasswordCreatedAt(time());



-        if (!$this->getCustomerId() && $customer = $observer->getEvent()->getCustomer()) {
+        if ($customer = $observer->getEvent()->getCustomer()) {

> app/code/core/Mage/Log/Model/Visitor.php

    -        if (!$this->getCustomerId() && $customer = $observer->getEvent()->getCustomer()) {
    +        if ($customer = $observer->getEvent()->getCustomer()) {

app/code/core/Mage/Usa/Helper/Data.php

+
+    /**
+     * Validate ups type value
+     *
+     * @param $valueForCheck string ups type value for check
+     *
+     * @return bool
+     */
+    public function validateUpsType($valueForCheck) {
+        $result = false;
+        $sourceModel = Mage::getSingleton('usa/shipping_carrier_ups_source_type');
+        foreach ($sourceModel->toOptionArray() as $allowedValue) {
+            if (isset($allowedValue['value']) && $allowedValue['value'] == $valueForCheck) {
+                $result = true;
+                break;
+            }
+        }
+        return $result;
+    }
 }

cron.php

cron.php : exception handle in cron.php file

-Mage::app('admin')->setUseSessionInUrl(false);
+try {
+    Mage::app('admin')->setUseSessionInUrl(false);
+} catch (Exception $e) {
+    Mage::printException($e);
+    exit;
+}

lib/Varien/Image/Adapter/Gd2.php

GD2 : return real mime type.

+        header("Content-type: ".$this->getMimeTypeWithOutFileType());

+
+    /**
+     * Gives real mime-type with not considering file type field
+     *
+     * @return string
+     */
+    public function getMimeTypeWithOutFileType()
+    {
+        return $this->_fileMimeType;
+    }
 }

js/tiny_mce/plugins/media/.htaccess

If you use nginx instead of Apache, make sure you update your configuration to duplicate this change.

+<IfModule mod_rewrite.c>
+    <Files moxieplayer.swf>
+        RewriteEngine on
+        RewriteCond %{QUERY_STRING} !^$
+        RewriteRule ^(.*)$ %{REQUEST_URI}? [R=301,L]
+    </Files>
+</IfModule>

app/design/adminhtml/default/default/template/system/shipping/ups.phtml

+if (!in_array($storedOriginShipment, array_keys($orShipArr))) {
+    $storedOriginShipment = '';
+}

+if ($storedFreeShipment != '' && !in_array($storedFreeShipment, array_keys($defShipArr))) {
+    $storedFreeShipment = '';
+}

+if (!Mage::helper('usa')->validateUpsType($storedUpsType)) {
+    $storedUpsType = '';
+}

Shipping method newly added/updated files are :

app/code/core/Mage/Usa/Helper/Data.php
app/code/core/Mage/Usa/Model/Shipping/Carrier/Abstract/Backend/Abstract.php
app/code/core/Mage/Usa/Model/Shipping/Carrier/Ups/Backend/Freemethod.php
app/code/core/Mage/Usa/Model/Shipping/Carrier/Ups/Backend/OriginShipment.php
app/code/core/Mage/Usa/Model/Shipping/Carrier/Ups/Backend/Type.php

Escapehtml files:

Downloadable product frontend files: Anyone using downloadable product please update the files in your theme files.

app/design/frontend/base/default/template/downloadable/catalog/product/links.phtml

Check code

<dt><label<?php if ($_isRequired) echo ' class="required"' ?>><?php if ($_isRequired) echo '<em>*</em>' ?><?php echo
    > $this->getLinksTitle() ?></label></dt>

Replace with

<dt><label<?php if ($_isRequired) echo ' class="required"' ?>><?php if ($_isRequired) echo '<em>*</em>' ?><?php echo
    > $this->escapeHtml($this->getLinksTitle()); ?></label></dt>

app/design/frontend/base/default/template/downloadable/checkout/cart/item/default.phtml

Check code

<dt><?php echo $this->getLinksTitle() ?></dt>

Replace with

 <dt><?php echo $this->escapeHtml($this->getLinksTitle()); ?></dt>

app/design/frontend/base/default/template/downloadable/sales/order/items/renderer/downloadable.phtml

Check code

<dt><?php echo $this->getLinksTitle() ?></dt>

Replace with

<dt><?php echo $this->escapeHtml($this->getLinksTitle()); ?></dt>

app/design/frontend/default/iphone/template/downloadable/checkout/cart/item/default.phtml

Check code

<dt><?php echo $this->getLinksTitle() ?></dt>

Replace with

<dt><?php echo $this->escapeHtml($this->getLinksTitle()); ?></dt>

app/design/frontend/default/iphone/template/downloadable/checkout/onepage/review/item.phtml Check code

`<dt><?php echo $this->getLinksTitle() ?></dt>`

Replace with

`<dt><?php echo $this->escapeHtml($this->getLinksTitle()); ?></dt>`

app/design/frontend/rwd/default/template/downloadable/checkout/cart/item/default.phtml Check code

`<dt><?php echo $this->getLinksTitle() ?></dt>`

Replace with

`<dt><?php echo $this->escapeHtml($this->getLinksTitle()); ?></dt>`

app/design/frontend/rwd/default/template/downloadable/checkout/onepage/review/item.phtml

Check code

<dt><?php echo $this->getLinksTitle() ?></dt>

Replace with

<dt><?php echo $this->escapeHtml($this->getLinksTitle()); ?></dt>

app/design/frontend/rwd/default/template/downloadable/sales/order/items/renderer/downloadable.phtml

Check code

<dt><?php echo $this->getLinksTitle() ?></dt>

Replace with

<dt><?php echo $this->escapeHtml($this->getLinksTitle()); ?></dt>

Other Escapehtml files:

app/code/core/Mage/Adminhtml/Block/Catalog/Product/Composite/Fieldset/Options.php

+        if (!empty($option['file_extension'])) {
+            $option['file_extension'] = $this->escapeHtml($option['file_extension']);
+        }

app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Options/Option.php

-                    $value['file_extension'] = $option->getFileExtension();
+                    $value['file_extension'] = $this->escapeHtml($option->getFileExtension());

app/design/frontend/enterprise/default/template/cms/hierarchy/pagination.phtml

-    <li><a title="<?php echo $this->escapeHtml($node->getLabel())?>" href="<?php echo $node->getUrl()?>"><?php echo $this->getNodeLabel($node)?></a></li>

+    <li><a title="<?php echo $this->escapeHtml($node->getLabel())?>" href="<?php echo $node->getUrl()?>"><?php echo $this->escapeHtml($this->getNodeLabel($node)); ?></a></li>
  • in app/code/core/Mage/Checkout/controllers/CartController.php, on which page in checkout do you usually see Form-key error? – Icon Jun 27 at 20:48
  • 1
    I do not see any form key error. if anyone overrides default/template/checkout/cart.phtml file and missed formkey. it will through redirect home page not through error. it is a checklist. if an error occurs please check form key :). Thanks for asking questions :) – Rama Chandran M Jun 27 at 21:13
  • I don't think it is very useful to post all of the patch diffs here. I'm more interested in actual possible issues... – 7ochem Jul 11 at 10:47
  • Thanks for your the comment. I feel it is useful for others because of it easy to find what are the files changed and what are core code changes. Example app/design/frontend/rwd/default/template/downloadable/checkout/onepage/review/item.phtml suppose we override in your theme just change the code easiy also it is more are like checklist. – Rama Chandran M Jul 11 at 17:23

The modification to the overloaded filter method in Zend_Filter_PregReplace is naive, and assumes that $this->_matchPattern is always a string. This property is subsequently provided as the first argument to preg_replace. In reality, an array is also a perfectly valid argument. This fact is actually used by multiple core Zend_Filter classes (such as Zend_Filter_Word_SeparatorToCamelCase). So any extension / branch of code that uses this filter or one of it's derivatives, with an array argument for _matchPattern, will start throwing Warning: substr() expects parameter 1 to be a string, array given.

A crude example of what it probably should do would be something along the lines of:

/**
 * Perform regexp replacement as filter
 *
 * @param  string $value
 * @return string
 */
public function filter($value)
{
    if ($this->_matchPattern == null) {
        #require_once 'Zend/Filter/Exception.php';
        throw new Zend_Filter_Exception(get_class($this) . ' does not have a valid MatchPattern set.');
    }

    $patterns = is_array($this->_matchPattern) ? $this->_matchPattern : array($this->_matchPattern);
    foreach ($patterns as $pattern) {
        if ($this->_containsEvalModifier($pattern)) {
            throw new Zend_Filter_Exception(get_class($this) . ' uses deprecated modifier "/e".');
        }
    }

    return preg_replace($this->_matchPattern, $this->_replacement, $value);
}

/**
 * Check if the modifiers contains the eval flag.
 *
 * @param  string $value
 * @return bool
 */
protected function _containsEvalModifier($pattern)
{
    $firstDelimiter = substr($pattern, 0, 1);
    $partsOfRegex = explode($firstDelimiter, $pattern);
    $modifiers = array_pop($partsOfRegex);

    return ($modifiers != str_replace('e', '', $modifiers));
}

Though I haven't done any thorough testing of this yet.

EDIT: It's worth noting, that whilst the proposed solution above should prevent the errors, the implementation is technically still a bit naive and prone to false positives. It assumes that the regex delimiter separating the pattern from the modifiers is the same as the one at the start of the string. Technically this doesn't have to be the case since PHP supports various bracket style delimiters. Therefore the valid input {hello}is will determine the modifiers are hello}is (rather than the actual modifiers of is) and thus will throw an exception, even though the pattern does not actually include the e modifier.

1.7.0.2 Version Issue: After installing the patch and go to one page checkout (generic Magento checkout), get this error

Parse error: syntax error, unexpected

app/code/core/Mage/Checkout/Model/Type/Onepage.php on line 691

Reversing the patch, error disappears.

Looking deeper into this question, I have found the patch has added the following line to onepage.php file.

$passwordCreatedTime = $this->_checkoutSession->getData('_session_validator_data')['session_expire_timestamp']
            - Mage::getSingleton('core/cookie')->getLifetime();
        $customer->setPasswordCreatedAt($passwordCreatedTime);

SOLUTION: Thanks to @FabianSchmengler

UPDATE TO PHP version 5.4 and up!

  • i am also applied the patch original it will be $passwordCreatedTime = $this->_checkoutSession->getData('_session_validator_data')['session_expire_timestamp'] - Mage::getSingleton('core/cookie')->getLifetime(); next line (new line created/added) - Mage::getSingleton('core/cookie')->getLifetime(); created cause of problem – Rama Chandran M Jun 27 at 18:30
  • 1
    yes i will check another project and provide more detail Ans :) – Rama Chandran M Jun 27 at 18:38
  • 2
    @Icon there was a patch for PHP 5.4 compatibility. I did not touch any 1.7 installation for a long time, but would expect it to work on 5.6 as well, give it a try. – Fabian Schmengler Jun 27 at 18:58
  • 1
    @FabianSchmengler Thanks for Ans :) . – Rama Chandran M Jun 27 at 19:01
  • 1
    @icon you can ignore deprecation notices for the time being, this will become relevant when you update to PHP 7 – Fabian Schmengler Jun 28 at 18:55

known issue :-

If your custom code or extension is using Zend/Filter/PregReplace.php with the modifier e, it will now return an error due to possible RCE issues.

This patch follows below security.

1) Extra admin session validation password change

+++ app/code/core/Mage/Admin/Model/User.php

+            $sessionUser = $this->getSession()->getUser();
+            if ($sessionUser && $sessionUser->getId() == $this->getId()) {
+                $this->getSession()->setUserPasswordChanged(true);
+            }

and then

+    /**
+     * @return Mage_Admin_Model_Session
+     */
+    protected function getSession()
+    {
+        return  Mage::getSingleton('admin/session');
+    }
+

class Mage_Admin_Model_User

+        $oldPassword = $this->getPassword();
     $this->setId(null);
     $this->load($id);
+        $isUserPasswordChanged = $this->getSession()->getUserPasswordChanged();
+        if ($this->getPassword() !== $oldPassword && !$isUserPasswordChanged) {
+            $this->setId(null);
+        } elseif ($isUserPasswordChanged) {
+            $this->getSession()->setUserPasswordChanged(false);
+        }

2) File Extension validation

app/code/core/Mage/Adminhtml/Block/Catalog/Product/Composite/Fieldset/Options.php

+        if (!empty($option['file_extension'])) {
+            $option['file_extension'] = $this->escapeHtml($option['file_extension']);
+        }

app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Options/Option.php app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Options/Option.php

-                    $value['file_extension'] = $option->getFileExtension();
+                    $value['file_extension'] = $this->escapeHtml($option->getFileExtension());

app/code/core/Mage/Catalog/Model/Product.php

+                        if (!empty($option['file_extension'])) {
+                            $fileExtension = $option['file_extension'];
+                            if (0 !== strcmp($fileExtension, Mage::helper('core')->removeTags($fileExtension))) {
+                                Mage::throwException(Mage::helper('catalog')->__('Invalid custom option(s).'));
+                            }
+                        }

3) Escape Html added for XSS

+++ app/code/core/Mage/Adminhtml/Block/Widget/Grid/Column/Filter/Datetime.php

-            return $value;
+            return $this->escapeHtml($value);
     }

-        return parent::getEscapedValue($index);
+        return $this->escapeHtml(parent::getEscapedValue($index));

app/design/frontend/base/default/template/downloadable/catalog/product/links.phtml

-        <dt><label<?php if ($_isRequired) echo ' class="required"' ?>><?php if ($_isRequired) echo '<em>*</em>' ?><?php echo $this->getLinksTitle() ?></label></dt>
+        <dt><label<?php if ($_isRequired) echo ' class="required"' ?>><?php if ($_isRequired) echo '<em>*</em>' ?><?php echo $this->escapeHtml($this->getLinksTitle()); ?></label></dt>

app/design/frontend/base/default/template/downloadable/checkout/cart/item/default.phtml

-            <dt><?php echo $this->getLinksTitle() ?></dt>
+            <dt><?php echo $this->escapeHtml($this->getLinksTitle()); ?></dt>

app/design/frontend/base/default/template/downloadable/checkout/onepage/review/item.phtml

-            <dt><?php echo $this->getLinksTitle() ?></dt>
+            <dt><?php echo $this->escapeHtml($this->getLinksTitle()); ?></dt>

app/design/frontend/base/default/template/downloadable/sales/order/items/renderer/downloadable.phtml

-            <dt><?php echo $this->getLinksTitle() ?></dt>
+            <dt><?php echo $this->escapeHtml($this->getLinksTitle()); ?></dt>

app/design/frontend/default/iphone/template/downloadable/checkout/onepage/review/item.phtml

-                <dt><?php echo $this->getLinksTitle() ?></dt>
+                <dt><?php echo $this->escapeHtml($this->getLinksTitle()); ?></dt>

app/design/frontend/rwd/default/template/downloadable/checkout/cart/item/default.phtml

-            <dt><?php echo $this->getLinksTitle() ?></dt>
+            <dt><?php echo $this->escapeHtml($this->getLinksTitle()); ?></dt>

app/design/frontend/rwd/default/template/downloadable/checkout/onepage/review/item.phtml

-            <dt><?php echo $this->getLinksTitle() ?></dt>
+            <dt><?php echo $this->escapeHtml($this->getLinksTitle()); ?></dt>

app/design/frontend/rwd/default/template/downloadable/sales/order/items/renderer/downloadable.phtml

-            <dt><?php echo $this->getLinksTitle() ?></dt>
+            <dt><?php echo $this->escapeHtml($this->getLinksTitle()); ?></dt>

4) XPath expression for checking layout update

app/code/core/Mage/Adminhtml/Model/LayoutUpdate/Validator.php

+    /**
+     * XPath expression for checking layout update
+     *
+     * @var array
+     */
+    protected $_disallowedXPathExpressions = array(
+        '*//template',
+        '*//@template',
+        '//*[@method=\'setTemplate\']',
+        '//*[@method=\'setDataUsingMethod\']//*[text() = \'template\']/../*'
+    );
+

Mage_Adminhtml_Model_LayoutUpdate_Validator

-        if ($templatePaths = $value->xpath('*//template | *//@template | //*[@method=\'setTemplate\']/*')) {
+        if ($templatePaths = $value->xpath($this->_getXpathValidationExpression())) {

Mage_Adminhtml_Model_LayoutUpdate_Validator

+    /**
+     * Returns xPath for validate incorrect path to template
+     *
+     * @return string xPath for validate incorrect path to template
+     */
+    protected function _getXpathValidationExpression() {
+        return implode(" | ", $this->_disallowedXPathExpressions);
+    }
+



+    /**
+     * Returns xPath for validate incorrect path to template
+     *
+     * @return string xPath for validate incorrect path to template
+     */
+    protected function _getXpathValidationExpression() {
+        return implode(" | ", $this->_disallowedXPathExpressions);
+    }
+

app/code/core/Mage/Catalog/Model/Resource/Category/Tree.php

+            if (!preg_match("#^[0-9\/]+$#", $item['path'])) {
+                $item['path'] = '';
+            }

5) Authenticated SQL Injection when saving a category

app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController

+            if (isset($data['general']['path'])) {
+                unset($data['general']['path']);
+            }

6) Product validate app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php

+                $product->validate();

7) mimetype app/code/core/Mage/Adminhtml/controllers/Cms/Wysiwyg/ImagesController.php

+            $this->getResponse()->setHeader('Content-type', $image->getMimeTypeWithOutFileType());

app/code/core/Mage/Adminhtml/controllers/Cms/WysiwygController.php

+        $this->getResponse()->setHeader('Content-type', $image->getMimeTypeWithOutFileType());

lib/Varien/Image/Adapter/Gd2.php

-        header("Content-type: ".$this->getMimeType());
+        header("Content-type: ".$this->getMimeTypeWithOutFileType());


+
+    /**
+     * Gives real mime-type with not considering file type field
+     *
+     * @return string
+     */
+    public function getMimeTypeWithOutFileType()
+    {
+        return $this->_fileMimeType;
+    }

8) Customer Passsword createdat app/code/core/Mage/Adminhtml/controllers/CustomerController.php

+                    $customer->setPasswordCreatedAt(time());

app/code/core/Mage/Checkout/Model/Api/Resource/Customer.php

+        $customer->setPasswordCreatedAt(time());

app/code/core/Mage/Checkout/Model/Type/Onepage.php

+        $passwordCreatedTime = $this->_checkoutSession->getData('_session_validator_data')['session_expire_timestamp']
+            - Mage::getSingleton('core/cookie')->getLifetime();
+        $customer->setPasswordCreatedAt($passwordCreatedTime);

app/code/core/Mage/Core/Model/Session/Abstract/Varien.php

+    const VALIDATOR_PASSWORD_CREATE_TIMESTAMP   = 'password_create_timestamp';


+    /**
+     * Use password creation timestamp in validator key
+     *
+     * @return bool
+     */
+    public function useValidateSessionPasswordTimestamp()
+    {
+        return true;
+    }


+        if ($this->useValidateSessionPasswordTimestamp()
+            && isset($validatorData[self::VALIDATOR_PASSWORD_CREATE_TIMESTAMP])
+            && isset($sessionData[self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP])
+            && $validatorData[self::VALIDATOR_PASSWORD_CREATE_TIMESTAMP]
+            > $sessionData[self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP] - $this->getCookie()->getLifetime()
+        ) {
+            return false;
+        }

app/code/core/Mage/Customer/Helper/Data.php

+    /**
+     * Get customer password creation timestamp or customer account creation timestamp
+     *
+     * @param $customerId
+     * @return int
+     */
+    public function getPasswordTimestamp($customerId)
+    {
+        /** @var $customer Mage_Customer_Model_Customer */
+        $customer = Mage::getModel('customer/customer')
+            ->setWebsiteId(Mage::app()->getStore()->getWebsiteId())
+            ->load((int)$customerId);
+        $passwordCreatedAt = $customer->getPasswordCreatedAt();
+
+        return is_null($passwordCreatedAt) ? $customer->getCreatedAtTimestamp() : $passwordCreatedAt;
+    }
+

app/code/core/Mage/Customer/Model/Resource/Customer.php

-        $customer->setPassword($newPassword);
+        $customer->setPassword($newPassword)->setPasswordCreatedAt(time());
     $this->saveAttribute($customer, 'password_hash');
+        $this->saveAttribute($customer, 'password_created_at');

app/code/core/Mage/Customer/controllers/AccountController.php

+                $customer->setPasswordCreatedAt(time());

Mage_Customer_AccountController

+            $customer->setPasswordCreatedAt(time());
         $customer->save();

``

+                $customer->setPasswordCreatedAt(time());

app/code/core/Mage/Log/Model/Visitor.php

-        if (!$this->getCustomerId() && $customer = $observer->getEvent()->getCustomer()) {
+        if ($customer = $observer->getEvent()->getCustomer()) {

9) UPS Changes

app/code/core/Mage/Usa/Helper/Data.php

+
+    /**
+     * Validate ups type value
+     *
+     * @param $valueForCheck string ups type value for check
+     *
+     * @return bool
+     */
+    public function validateUpsType($valueForCheck) {
+        $result = false;
+        $sourceModel = Mage::getSingleton('usa/shipping_carrier_ups_source_type');
+        foreach ($sourceModel->toOptionArray() as $allowedValue) {
+            if (isset($allowedValue['value']) && $allowedValue['value'] == $valueForCheck) {
+                $result = true;
+                break;
+            }
+        }
+        return $result;
+    }

ADDED files for UPS

`app/code/core/Mage/Usa/Model/Shipping/Carrier/Abstract/Backend/Abstract.php` 
`app/code/core/Mage/Usa/Model/Shipping/Carrier/Ups/Backend/Freemethod.php`
`app/code/core/Mage/Usa/Model/Shipping/Carrier/Ups/Backend/OriginShipment.php`
`app/code/core/Mage/Usa/Model/Shipping/Carrier/Ups/Backend/Type.php`

Added Setting for this new functoinlaity

app/code/core/Mage/Usa/etc/system.xml

+                            <backend_model>usa/shipping_carrier_ups_backend_freemethod</backend_model>

843 line

+                            <backend_model>usa/shipping_carrier_ups_backend_originShipment</backend_model>

886

+                            <backend_model>usa/shipping_carrier_ups_backend_type</backend_model>

app/design/adminhtml/default/default/template/system/shipping/ups.phtml

+if (!in_array($storedOriginShipment, array_keys($orShipArr))) {
+    $storedOriginShipment = '';
+}
+if ($storedFreeShipment != '' && !in_array($storedFreeShipment, array_keys($defShipArr))) {
+    $storedFreeShipment = '';
+}
+if (!Mage::helper('usa')->validateUpsType($storedUpsType)) {
+    $storedUpsType = '';
+}
 ?>

10) Zend class added

`app/code/core/Zend/Filter/PregReplace.php`
`app/code/core/Zend/Validate/EmailAddress.php`

1> 1) Bundle Product validation

app/design/adminhtml/default/default/template/bundle/product/edit/bundle/option.phtml

+    <?php $_selection->setSku($this->escapeHtml($_selection->getSku())); ?>

12) Admin session in try catch in cron.php

-Mage::app('admin')->setUseSessionInUrl(false);
+try {
+    Mage::app('admin')->setUseSessionInUrl(false);
+} catch (Exception $e) {
+    Mage::printException($e);
+    exit;
+}

Looks like part of the patch is htmlEscaping all "getLinksTitle()". But they forgot the following files (this is based on 1.8.1).

app/design/frontend/base/default/template/downloadable/checkout/multishipping/item/downloadable.phtml

app/design/frontend/base/default/template/downloadable/email/order/items/creditmemo/downloadable.phtml

app/design/frontend/base/default/template/downloadable/email/order/items/invoice/downloadable.phtml

app/design/frontend/base/default/template/downloadable/email/order/items/order/downloadable.phtml

app/design/frontend/base/default/template/downloadable/sales/order/creditmemo/items/renderer/downloadable.phtml

app/design/frontend/base/default/template/downloadable/sales/order/invoice/items/renderer/downloadable.phtml

app/design/frontend/default/iphone/template/downloadable/sales/order/creditmemo/items/renderer/downloadable.phtml

app/design/frontend/default/iphone/template/downloadable/sales/order/invoice/items/renderer/downloadable.phtml

Patch does not work on vanilla Magento CE 1.8.0.0

Update: Added solution below.

Problem:

file app/design/frontend/base/default/template/downloadable/sales/order/items/renderer/downloadable.phtml
Hunk #1 FAILED at 54.

Applied previous patches:

  • APPSEC-212
  • SUPEE-2619
  • SUPEE-2725
  • SUPEE-3941
  • SUPEE-5344
  • SUPEE-5994
  • SUPEE-6237
  • SUPEE-6285
  • SUPEE-6482
  • SUPEE-6788
  • SUPEE-7405
  • SUPEE-7405v.1.1
  • SUPEE-7616
  • SUPEE-8167
  • SUPEE-8788v2
  • SUPEE-8967
  • SUPEE-9652
  • SUPEE-9767v2
  • SUPEE-10336
  • SUPEE-10266
  • SUPEE-10415
  • SUPEE-10570v2

Solution

Fixed by editing the patch file. Replaced the patch for downloadable.phtml by the one from the patch for v1.7.0.2 in the original patch file these are lines 1854-1862.

This is mainly due to indentation in the file. As the changes for downloadable.phtml in V1.7.0.2 have more indented.

Solution 2

I had a similar problem, but I was able to fix by re-saving the original file in an editor which forced line ending to be Unix style LF's, not the Windows style CRLF's or the Mac CR's

In reference to Matt Antley, maybe they did not include SUPEE-10570v2 because of this

Magento was recently informed about an issue with both patch SUPEE-10570 > and Magento versions 1.9.3.8/1.14.3.8 that could result in the inability > of customers to complete checkout when trying to register during checkout. Magento is now providing an updated patch (SUPEE-10570v2) that > no longer causes this issue. Note, however, that this new patch no longer > protects against two low risk session handling-related security issues that patch SUPEE-10570 protected against. https://magento.com/security/patches/supee-10570

As far as I know the checkout bug was not very common and so they decided to stay with SUPEE-10570 which protects against the two low risk security issues?!

  • +1 This is most likely the reason for it, still it's worth noting that if users are upgrading and had to apply SUPEE-10570v2 then they'll have to re-apply it. – Matt Antley Jun 28 at 22:16
  • As Peter O’Callaghan stated, changes from 10570v2 are reverted by 10752 so there’s no need to include the former. Since there’s no 10570v2 for 1.9.3.9, you’re not supposed to apply anything. The whole reasoning is weak: why should Magento keep its 1.9.3.9 branch on a different base than all the others? They even said they’ll base every future release and patch on 10570v2. – pong Jul 3 at 20:33
  • Thanks for the comments Peter and pong. Have removed my answer as it is misleading as stated by the both of you. It wasn't my intension, just something I didn't think through when writing it out and was something I briefly noticed when taking a look at SUPEE-10752 and jumped the gun a bit. Again, thanks for the comments. – Matt Antley Jul 3 at 22:08

Patch does not work on vanilla Magento CE 1.6.0.0

Update: Added solution below.

Problems:

file app/code/core/Mage/Admin/Model/User.php
Hunk #1 FAILED at 127.
...
file app/code/core/Mage/Customer/controllers/AccountController.php
Hunk #2 FAILED at 812.

Applied previous patches:

  • APPSEC-212
  • SUPEE-2631
  • SUPEE-2725
  • SUPEE-5344
  • SUPEE-5994
  • SUPEE-6237
  • SUPEE-6285
  • SUPEE-6482
  • SUPEE-6788
  • SUPEE-7405
  • SUPEE-7405v.1.1
  • SUPEE-8167
  • SUPEE-8788v2
  • SUPEE-8967
  • SUPEE-9652
  • SUPEE-9767v2
  • SUPEE-10266
  • SUPEE-10415
  • SUPEE-10570v2
  • SUPEE-10752

Solved

I have fixed this problem by changing the patch file. I replaced the hunks which gave the problems by the according ones from the patch for v1.5.1.0. In the original patch file these are lines 167-177 and 663-670.

In EE v1.14.2.4 after applying SUPEE-10752, I had to apply the following patch as well to fix the issue where the checkout redirects to the homepage instead of the success page:

File: invalid_session_fix-2018-03-14-05-10-19.patch

diff --git a/app/code/core/Mage/Core/Model/Session/Abstract/Varien.php b/app/code/core/Mage/Core/Model/Session/Abstract/Varien.php
index 59b3ea8..35155f1 100644
--- a/app/code/core/Mage/Core/Model/Session/Abstract/Varien.php
+++ b/app/code/core/Mage/Core/Model/Session/Abstract/Varien.php
@@ -485,7 +485,7 @@ class Mage_Core_Model_Session_Abstract_Varien extends Varien_Object
             && isset($validatorData[self::VALIDATOR_PASSWORD_CREATE_TIMESTAMP])
             && isset($sessionData[self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP])
             && $validatorData[self::VALIDATOR_PASSWORD_CREATE_TIMESTAMP]
-            > $sessionData[self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP] - $this->getCookie()->getLifetime()
+            > $sessionData[self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP]
         ) {
             return false;
         }

The above fix is found in https://magento.com/tech-resources/download under SUPEE-10570 > invalid_session_fix.patch (0 MB)

  • It also does the same with CE 1.9.3.6 when php is < 5.5, Thanks for the fix – GunJan Mehta Oct 25 at 8:19

On 1.6, the ups.phtml patch is broken. It's referencing $storedOriginShipment, $storedFreeShipment which have a typo in 1.6 ($stroredOriginShipment and $stroredFreeShipment). Furthermore it references $storedUpsType which doesn't exist at all in 1.6.

We saw a blank page at /checkout/* after applying SUPEE-10752 and compiling

version: 1.9.1.0

Triggering conditions:applying SUPEE-10752 + enable compiler + login as a customer, then visit /checkout/*

Just to clarify: With deactivated compiler all things went well, with activated compiler we only could see a blank cart page when logged in without any log entries (even after activating all possible logs and developer mode).

We've encountered a problem on 1.9.1.0 and 1.9.2.4 (haven't tested on others). It doesn't appear on all of our projects, but it has repeated on several of them. We think it might be affecting the projects that had SUPEE-10570v1 installed at some point.

After applying the patch, if a user logs in, they will see their account page perfectly fine. However, if they try to return to any other page on the site, the page will stop responding and they'll see either a blank screen or a 502 Bad Gateway. This is due to to PHP going into an infinite loop and either segfaulting or being stopped by the its .ini settings.

I've managed to dig up that the problem is an infinite recursion on the line that loads the $customer in \app\code\core\Mage\Customer\Helper\Data.php, getPasswordTimestamp().

$customer = Mage::getModel('customer/customer')
        ->setWebsiteId(Mage::app()->getStore()->getWebsiteId())
        ->load((int)$customerId);

When looking at the stack trace of the infinite recursion, it keeps looping back into this over and over again. Somehow, it seems the ->load() ends up calling the getPasswordTimestamp() method.

The workaround given in https://magento.stackexchange.com/a/235984/67252 works fine, but I would like to know what's happening.

I have encountered a problem after this patch. I can't set "Free Method" for "UPS Type" "United Parcel Service XML". Magento throws an error when any method is selected in "Free Method" drop-down. Error: "Field "Ups Free Method" has wrong value."

Is anyone has faced the same issue and got the solution?

Thanks in advance!

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.