Security Patch SUPEE-9767 - Possible issues?

Here's my overview of the patch after digging into it

TIME SAVER : Experius provides a patch helper that helps you finding the files in custom themes, custom modules or local overwrites that also might need to be patched manually, you can find it here: https://github.com/experius/Magento-1-Experius-Patch-Helper#magento

Checkout form keys

As said in the other post, this patch adds form keys to the following forms:

Shipping cart form:

app/design/frontend/<package>/<theme>/template/checkout/cart/shipping.phtml

Multishipping billing checkout form:

app/design/frontend/<package>/<theme>/template/checkout/multishipping/billing.phtml

Multishipping shipping checkout form:

app/design/frontend/<package>/<theme>/template/checkout/multishipping/shipping.phtml

Multishipping addresses checkout form:

app/design/frontend/<package>/<theme>/template/checkout/multishipping/addresses.phtml

Billing checkout form:

app/design/frontend/<package>/<theme>/template/checkout/onepage/billing.phtml

Shipping checkout form:

app/design/frontend/<package>/<theme>/template/checkout/onepage/shipping.phtml

Payment checkout form:

app/design/frontend/<package>/<theme>/template/checkout/onepage/payment.phtml

Shipping method checkout form:

app/design/frontend/<package>/<theme>/template/checkout/onepage/shipping_method.phtml

Persistent Billing checkout form:

app/design/frontend/<package>/<theme>/template/persistent/checkout/onepage/billing.phtml

On top of that the following JS files have been updated to be compatible with that change:

  • js/varien/payment.js
  • skin/frontend/base/default/js/opcheckout.js

What to do:

If you're using with custom versions of those templates you'll have to update them by adding the following code into them:

<?php echo $this->getBlockHtml('formkey') ?>

If you're using a 3rd party checkout module, you'll have to get in touch with them so they can provide an updated version of their module.

Also if you have custom versions of the previously listed JS files, you'll have to update them too.

SAVE YOUR TIME:

Fabian Schmengler wrote a nice little script to update all those things for you, you can find it here:

https://gist.github.com/schmengler/c42acc607901a887ef86b4daa7a0445b

IMPORTANT NOTE : the checkout formkey validation can be changed in the backend via a new config field under System > Configuration > Admin > Security > Enable Form Key Validation On Checkout . THIS IS NOT ENABLED BY DEFAULT so you'll have to enable it to benefit from this security feature!!! Note that you'll get a notice in the backend if it's not enabled.

Image Upload callback

The image gallery controller has been updated to add a validation callback.

What to do

If you're using a custom module that does image upload with code that looks like this:

        $uploader = new Mage_Core_Model_File_Uploader('image');
        $uploader->setAllowedExtensions(array('jpg','jpeg','gif','png'));
        $uploader->addValidateCallback('catalog_product_image',
            Mage::helper('catalog/image'), 'validateUploadFile');
        $uploader->setAllowRenameFiles(true);
        $uploader->setFilesDispersion(true);

I strongly suggest you update that code by adding the following piece after it:

        $uploader->addValidateCallback(
            Mage_Core_Model_File_Validator_Image::NAME,
            Mage::getModel('core/file_validator_image'),
            'validate'
        );

Symlinks

This patch removes the system configuration field that allows you to allow template symlinks in the backend. It used to be under System > Configuration > Developer > Template > Allow Symlinks . Now the entire Template section is gone.

On top of that, that field is now disabled by default via the app/etc/config.xml

The funny thing here is that you'll get a notice in the backend if you have that configuration field enabled prior to the patch but you won't be able to disable it as the field is gone.

Only way of doing it is by running the following SQL query

UPDATE core_config_data SET value = 0 WHERE path = "dev/template/allow_symlink";

Clarification

First I strongly suggest you check those two posts that will help you understand the purpose of that Symlink modification:

  • From Peter O'Collaghan: https://peterocallaghan.co.uk/2017/06/appsec-1281-dangerous-symlinks/
  • From Max Chadwick: https://maxchadwick.xyz/blog/what-allow-symlinks-actually-does

This modification is really about calling uploadable content (like images) via template directives.

The issue related to symlinks is exploitable only with admin access and Magento added some more protection around image uploads as well.

Please note that they are some protections against known way to exploit it in addition to the setting itself.

What to do: if like me, you're using modman or composer with template symlinks, you're gonna face some issues. I'm still trying to find out what's the best thing to do here apart from dealing with SQL queries.

Main post regarding this issue: SUPEE-9767, modman and symlinks

List of possible issues

V2 was released since that original post. Don't forget to upgrade

Bugs

The word 'confirmed' is used for confirmed bugs. If it's not there, that means it could be a bug but hasn't been confirmed yet.

  • Customer registration fails at checkout CONFIRMED & FIXED IN V2
  • PHP7 and EE bug CONFIRMED
  • Bug with EE, FPC and Design Exceptions CONFIRMED
  • Add to cart and cookie bug in EE CONFIRMED
  • Multishipping broken after patch CONFIRMED
  • Missing bug fix in head-simple.phtml CONFIRMED & FIXED IN V2
  • Admin Symlink warning is not displayed on 1.9.2 CONFIRMED & FIXED IN V2
  • Watermark get black background when transparent CONFIRMED & FIXED IN V2
  • Unable to upgrade via Magento Connect
  • Infinite redirect loop on 1.6.0.0

Hunk Failed Issues

Note that all those issues could be simply because you modified the original file, to double check that this is not the case:

  • Backup the file where you get the Hunk Failed error
  • Download the original file from your Magento version
  • Compare both files

If files are different you'll have to apply the patch with the original file then reapply your custom changes the clean way such as:

  • custom template in a custom theme folder
  • local.xml
  • app/code/local file

If files are not different then this is either a permission issue or a "bug" in the patch.

  • patching file app/design/frontend/rwd/default/layout/page.xml Hunk #1 FAILED at 36.
  • patching file app/design/frontend/enterprise/default/template/persistent/checkout/onepage/billing.phtml Hunk #1 FAILED at 225.
  • patching file app/code/core/Enterprise/PageCache/Model/Observer.php Hunk #6 FAILED at 1093.
  • patching file app/code/core/Mage/Core/etc/system.xml Hunk #3 FAILED at 1355.
  • patching file app/code/core/Mage/Sales/Model/Quote/Item.php Hunk #1 FAILED at 500.
  • Hunk failed on 1.8.0.0

Issue1: form_key invalid at checkout onepage

Magento add form_key at most of the forms.

if you have using default onepage and using custom theme, then you will start getting **form_key issue at checkout each step **;

you should add form key at <?php echo $this->getBlockHtml('formkey') ?>

to form of each checkout step files if below files exits,

  • app/design/frontend/[Your_Package]/[YOUR_THEME]/template/checkout/onepage/billing.phtml
  • app/design/frontend/[Your_Package]/[YOUR_THEME]/template/checkout/onepage/payment.phtml
  • app/design/frontend/[Your_Package]/[YOUR_THEME]/template/checkout/onepage/shipping.phtml

  • app/design/frontend/[Your_Package]/[YOUR_THEME]/template/checkout/onepage/shipping_method.phtml

if the template files are calling from base theme then it does not create problem.Because patch will automatically update those files.

Also note: <?php echo $this->getBlockHtml('formkey') ?> should always inside of form tag

 <form action="" .....>
     <fieldset>
      .......
       <?php echo $this->getBlockHtml('formkey') ?>
     </fieldset>
 </form>

** If you using Magento multi-shipping checkout then need to done at

below files:

Issue2: form_key issue to Shipping estimation form at cart page:

Add form_key at estimates shipping form at cart page

Then must add form key <?php echo $this->getBlockHtml('formkey') ?>

at app/design/frontend/{Your_Package}/{YOUR_THEME]/template/checkout/cart/shipping.phtml

Issue3: Magento onepage checkout opcheckout.js error

If you using default onepage checkout and have opcheckout.js then should check

if (elements[i].name=='payment[method]' || elements[i].name == 'form_key') {is available at opcheckout.js

If not exits then replace

if (elements[i].name=='payment[method]') {

with

if (elements[i].name=='payment[method]' || elements[i].name == 'form_key') {

For case of issue1,issue2, issue3, Issue can fix easily by using @FabianSchmengler 's script add-checkout-form-key.sh. It will fix the issue on your receptive theme files

Issue4: Invalid form key after customer login when Mage_Customer_Model_Session rewrite

If Mage_Customer_Model_Session class rewrite or have called from

app/code/local/Mage/Customer/Model/Session.php then you may be get form_key issue when we set a customer for the session using setCustomerAsLoggedIn() /or after a customer set at session .

In this case, you must be add

Mage::getSingleton('core/session')->renewFormKey();

at setCustomerAsLoggedIn() before call of

Mage::dispatchEvent('customer_login', array('customer'=>$customer));

  public function setCustomerAsLoggedIn($customer)
    {
        $this->setCustomer($customer);
        $this->renewSession();
        // add this  for patch -9767
        Mage::getSingleton('core/session')->renewFormKey();
       // end this for patch 9767
        Mage::dispatchEvent('customer_login', array('customer'=>$customer));
        return $this;
    }

Issue5: Form_key issue after logout

After logout customer from session, you may be start session issue if If Mage_Customer_Model_Session class rewrite or have called from

app/code/local/Mage/Customer/Model/Session.php

In those same need for this case:

   protected function _logout()
    {
        $this->setId(null);
        $this->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID);
        $this->getCookie()->delete($this->getSessionName());
// add this  for patch -9767
Mage::getSingleton('core/session')->renewFormKey();
        return $this;
    }

Recommendation:

Recommendation1: For fixed the issue of supee-9767, you can use the patch https://github.com/experius/Magento-1-Experius-Patch-Helper

This is one best solution for now.

Note, before do that I am strongly recommended to take files and database backup or full system backup.


Recommendation2: Use patch feature on your ONESTEP CHECKOUT

We know that patch supee-9767 release for security purpose, the if you using ONESTEP CHECKOUT then you should add form_key validation to SAVE action of your onestep checkout controller.

Suppose for save shipping method details, your onestep checkout have using saveShippingmethod() Then on this you should add

if ($this->isFormkeyValidationOnCheckoutEnabled() && !$this->_validateFormKey()) {
           return;
      }

Also on youmust add form key <?php echo $this->getBlockHtml('formkey') ?> at your onestep checkout phtml files respective section

Some related link

https://peterocallaghan.co.uk/2017/06/appsec-1281-dangerous-symlinks/


Based on my first pass at review of the patch file...

  • A new setting admin/security/validate_formkey_checkout has been added. When turned on, checkout forms are checked for presence of a form key. If the template files are overriden in the theme they'll need to be updated there. This setting seems to be off by default
  • Symlinks seem to be disallowed by default (in app/etc/config.xml). Also, the ability to allow them seems to have been removed from the admin configuration. However, if your site previously explicitly enabled symlinks, the setting would be saved in the database, overriding this change.
  • You need to clear both the cache AND the full page cache when applying this patch. The design exceptions are saved in a format the is incompatible with decoding. You'll see an error like this "Decoding failed: Syntax error" if you don't flush page cache.