Magento patch SUPEE-6788: cosa cambia e come intervenire

(Aggiornato il 24/12/2015)

Prima di tutto riporto gli articoli ufficiali di Magento dalla quale ho reperito parte del materiale necessario per questa guida.

La Magento patch SUPEE-6788 è al momento quella che richiede più interventi sia a livello design che a livello codice applicazione.

1) (SOLO NGINX) MODIFICA ACCESSO FILE cron.php

Per chi utilizza nginx per il proprio sito è necessario aggiungere questa regola:

location ^~ /cron { deny all; }

2) MODIFICA ROUTING ADMINHTML (backend magento)

Tutte le estensioni di terze parti andrebbero aggiornate per evitare il bypass della url.

Viene richiesto di modificare l’etc/config.xml delle estensioni da:

<admin>
    <routers>
        <custom_module>
            <use>admin</use>
            <args>
                <module>custom_module</module>
                <frontName>custom_module</frontName>
            </args>
        </custom_module>
    </routers>
</admin>

con il seguente.

<admin>
    <routers>
        <adminhtml>
            <args>
                <modules>
                    <custom_module after="Mage_Adminhtml">CustomModule_Adminhtml</custom_module>
                </modules>
            </args>
        </adminhtml>
    </routers>
</admin>

Questa modifica fa si che i routing abilitati solo nel backend abbiano il suffisso “admin”.

IMPORTANTE! La modifica non è attiva di default quindi se avete estensioni non aggiornate, esse continueranno a funzionare. Solamente se si disabilita l’opzione in System > Configuration > Admin > Security -> “Enable Admin routing compatibility mode” allora le estensioni non funzioneranno.

3) PROTEZIONI DA SQL INJECTION

A) Codice non più consentito:
$collection->addFieldToFilter('`field`', array('eq'=>3));

Da sostituire con:

$collection->addFieldToFilter('field', array('eq'=>3));
B) Codice non più consentito:
$collection->addFieldToFilter('(field1-field2)', array('eq'=>3));

Da sostituire con:

$expression = '(field1-field2)';
$condition = $this->_getConditionSql($expression, array('eq'=>3));
$this->_select->where(condition);

Oppure con un approccio diverso:

Class T extends Mage_Core_Model_Resource_Db_Collection_Abstract {
...
protected $_map = array('fields' => array(
    'condition' => '(field1 – field2)',
);
...
public function someMethod() {
    $this->addFieldToFilter('condition', array('eq' => 3));
}
...
}

4) INTRODUZIONE DEI PERMESSI PER VARIABILI E BLOCCHI

Questa modifica riguarda soprattutto i template e il design in generale. Con questa patch nelle pagine CMS, blocchi statici, template email ecc… non è possibile inserire blocchi o variabili se non sono “autorizzati”. Vengono create due nuove tabelle “core”: ‘permission_block’ e ‘permission_variable’

BLOCCHI

Sono identificati dal codice {{block type=”…. e ogni tipologia deve essere nella lista (autorizzata) sotto System > Permissions > Blocks Di base vengono inseriti questi blocchi:

core/template
catalog/product_new
enterprise_catalogevent/event_lister (in Magento Enterprise Edition)

Vi consiglio alla lista di aggiungere anche:

newsletter/subscribe
catalog/product_list_related
VARIABILI

Sono identificati dal codice {{config path=”…. e ognuna deve essere nella lista (autorizzata) sotto System > Permissions > Variables Di base vengono inserite queste variabili:

web/unsecure/base_url
web/secure/base_url
trans_email/ident_support/name
trans_email/ident_support/email
trans_email/ident_general/name
trans_email/ident_general/email
trans_email/ident_sales/name
trans_email/ident_sales/email
trans_email/ident_custom1/name
trans_email/ident_custom1/email
trans_email/ident_custom2/name
trans_email/ident_custom2/email
general/store_information/name
general/store_information/phone
general/store_information/address

Se volete aggiungere nuove variabili o blocchi basta andare nell’apposita sezione nel backend magento.

variabili blocchi

5) MAGGIORE SICUREZZA PER IL RESET PASSWORD ACCOUNT UTENTE

FORM KEY

Viene introdotto il form_key nella registrazione utente.
I seguenti file vengono coinvolti:

  • base/default/template/customer/form/register.phtml
  • base/default/template/persistent/customer/form/register.phtml
  • rwd/default/template/persistent/customer/form/register.phtml

Quindi è necessario controllare il proprio template e aggiungere ai file phtml:

  • <your package>/<your design>/template/customer/form/register.phtml
  • <your package>/<your design>/template/persistent/customer/form/register.phtml

Questa stringa di codice:

<input type="hidden" name="form_key" value="<?php echo Mage::getSingleton('core/session')->getFormKey() ?>" />

dopo:

<input type="hidden" name="error_url" value="<?php echo $this->getErrorUrl() ?>" />

Esempio:

PRIMA
.......   
 <form action="<?php echo $this->getPostActionUrl() ?>" method="post" id="form-validate">
        <div class="fieldset">
            <input type="hidden" name="success_url" value="<?php echo $this->getSuccessUrl() ?>" />
            <input type="hidden" name="error_url" value="<?php echo $this->getErrorUrl() ?>" />
            <h2 class="legend"><?php echo $this->__('Personal Information') ?></h2>
            <ul class="form-list">
                <li class="fields">
                    <?php echo $this->getLayout()->createBlock('customer/widget_name')->setObject($this->getFormData())->setForceUseCustomerAttributes(true)->toHtml() ?>
                </li>
                <li>
                    <label for="email_address" class="required"><em>*</em><?php echo $this->__('Email Address') ?></label>
                    <div class="input-box">
                        <input type="text" name="email" id="email_address" value="<?php echo $this->escapeHtml($this->getFormData()->getEmail()) ?>" title="<?php echo $this->__('Email Address') ?>" class="input-text validate-email required-entry" />
                    </div>
                </li>
.........
DOPO
.......   
 <form action="<?php echo $this->getPostActionUrl() ?>" method="post" id="form-validate">
        <div class="fieldset">
            <input type="hidden" name="success_url" value="<?php echo $this->getSuccessUrl() ?>" />
            <input type="hidden" name="error_url" value="<?php echo $this->getErrorUrl() ?>" />
            <!-- INTRODOTTO FORM KEY -->
            <input type="hidden" name="form_key" value="<?php echo Mage::getSingleton('core/session')->getFormKey() ?>" />
            <!-- /INTRODOTTO FORM KEY -->  
            <h2 class="legend"><?php echo $this->__('Personal Information') ?></h2>
            <ul class="form-list">
                <li class="fields">
                    <?php echo $this->getLayout()->createBlock('customer/widget_name')->setObject($this->getFormData())->setForceUseCustomerAttributes(true)->toHtml() ?>
                </li>
                <li>
                    <label for="email_address" class="required"><em>*</em><?php echo $this->__('Email Address') ?></label>
                    <div class="input-box">
                        <input type="text" name="email" id="email_address" value="<?php echo $this->escapeHtml($this->getFormData()->getEmail()) ?>" title="<?php echo $this->__('Email Address') ?>" class="input-text validate-email required-entry" />
                    </div>
                </li>
.........

Verificate che non abbiate estensioni che sovrascrivino nel package “base” questi file.
Per far prima, potete effettuare una ricerca per nome file (register.phtml) ed effettuare il fix ad ogni file che trovate.

LAYOUT RESET PASSWORD

Controllare il proprio template se è stato modificato il layout xml per la pagina del reset password. Nel caso in cui abbiate:

    <customer_account_resetpassword translate="label">
        <label>Reset a Password</label>
        <remove name="right"/>
        <remove name="left"/>
        <reference name="head">
            <action method="setTitle" translate="title" module="customer">
                <title>Reset a Password</title>
            </action>
        </reference>
        <reference name="root">
            <action method="setTemplate">
                <template>page/1column.phtml</template>
            </action>
            <action method="setHeaderTitle" translate="title" module="customer">
                <title>Reset a Password</title>
            </action>
        </reference>
        <reference name="content">
            <block type="customer/account_resetpassword" name="resetPassword" template="customer/form/resetforgottenpassword.phtml"/>
        </reference>
    </customer_account_resetpassword>

Sostituire con il nuovo che viene fornito nel “base”:

    <customer_account_changeforgotten translate="label">
        <label>Reset a Password</label>
        <remove name="right"/>
        <remove name="left"/>

        <reference name="head">
            <action method="setTitle" translate="title" module="customer">
                <title>Reset a Password</title>
            </action>
        </reference>
        <reference name="root">
            <action method="setTemplate">
                <template>page/1column.phtml</template>
            </action>
            <action method="setHeaderTitle" translate="title" module="customer">
                <title>Reset a Password</title>
            </action>
        </reference>
        <reference name="content">
            <block type="customer/account_changeforgotten" name="changeForgottenPassword" template="customer/form/resetforgottenpassword.phtml"/>
        </reference>
    </customer_account_changeforgotten>

altrimenti vi ritrovate pagina bianca nel caso di un reset password dei clienti.

6) APPLICAZIONE PATCH (no .htaccess.sample no patch)

Importante nota da non sottovalutare è il fatto che se non abbiamo nel sorgente il file .htaccess.sample la patch non viene applicata!
Quindi nel caso in cui non abbiate tale file, prendetelo dal sorgente magento e applicate la patch. Successivamente potrete rimuoverlo tranquillamente

CONSIGLI UTILI

Per molti sembra la solita “romanzina” ma ho visto ancora persone che applicano le patch in ambienti di produzione senza testarle, PER FAVORE NON FATELO!
Soprattutto per questa tipologia di patch, va testato il tutto in un ambiente di sviluppo locale!!!

  • effettuate un backup prima di applicare modifiche in produzione
  • utilizzate un sistema di versioning (es. git) per avere al meglio lo storico di ciò che è stato fatto
  • applicate la patch da shell (terminale)
  • affidatevi ad esperti se non sapete cosa dovete fare

Hai problemi dopo avere applicato la patch? Prova questo tool: https://github.com/rhoerr/supee-6788-toolbox

Commenti offerti da Disqus