Archivo de la categoría ‘OsCommerce’

osCommerce Update 060817

Jueves, 14 de Septiembre de 2006

Nueva revisión ya disponible desde el download de OsCommerce , osCommerce 2.2 Milestone 2 Update 060817

Los cambios en esta nueva revisión de oscommerce son los siguientes:

## Update 060817 (17th August 2006)

- Magic Quotes Compatibility Layer Fix
- Parse GET Variables In Cache Functions
- PHP 3 Session ID XSS Issue
- Product Attributes SQL Injection
- Resize Images To Round Numbers
- Use The Correct Country Name Value When Formatting Addresses
- Prevent The Session ID Being Passed In Tell-A-Friend E-Mails
- Properly Remove Deleted Products That Exist In Shopping Carts

Y estos son las soluciones , por si quieres actualizar tu oscommerce :

Cambio 1:

Reemplazar en catalog/includes/functions/compatibility.php:

Lineas 22-23, de:

if (is_array($value)) {
do_magic_quotes_gpc($value);

a:

if (is_array($ar[$key])) {
do_magic_quotes_gpc($ar[$key]);

Reemplazar en catalog/admin/includes/functions/compatibility.php:

Lineas 22-23, de:

if (is_array($value)) {
do_magic_quotes_gpc($value);

a:

if (is_array($ar[$key])) {
do_magic_quotes_gpc($ar[$key]);

——————————————————————————
Parse GET Variables In Cache Functions

http://svn.oscommerce.com/trac/changeset/708

——————————————————————————

Cambio 2:

Reemplazar en catalog/includes/functions/cache.php:

Linea 121, de:

if (isset($HTTP_GET_VARS['manufactuers_id']) && tep_not_null($HTTP_GET_VARS['manufacturers_id'])) {

a:

if (isset($HTTP_GET_VARS['manufactuers_id']) && is_numeric($HTTP_GET_VARS['manufacturers_id'])) {

Lineas 142-148, de:

if (($refresh == true) || !read_cache($cache_output, 'also_purchased-' . $language . '.cache' . $HTTP_GET_VARS['products_id'], $auto_expire)) {
ob_start();
include(DIR_WS_MODULES . FILENAME_ALSO_PURCHASED_PRODUCTS);
$cache_output = ob_get_contents();
ob_end_clean();
write_cache($cache_output, 'also_purchased-' . $language . '.cache' . $HTTP_GET_VARS['products_id']);
}

a:

$cache_output = '';

if (isset($HTTP_GET_VARS['products_id']) && is_numeric($HTTP_GET_VARS['products_id'])) {
if (($refresh == true) || !read_cache($cache_output, 'also_purchased-' . $language . '.cache' . $HTTP_GET_VARS['products_id'], $auto_expire)) {
ob_start();
include(DIR_WS_MODULES . FILENAME_ALSO_PURCHASED_PRODUCTS);
$cache_output = ob_get_contents();
ob_end_clean();
write_cache($cache_output, 'also_purchased-' . $language . '.cache' . $HTTP_GET_VARS['products_id']);
}
}

——————————————————————————
PHP 3 Session ID XSS Issue

http://svn.oscommerce.com/trac/changeset/709

——————————————————————————

Cambio 3:

Añadir a catalog/includes/classes/sessions.php:

Linea 380:

if (!empty($session->id)) {
if (preg_match('/^[a-zA-Z0-9]+$/', $session->id) == false) {
unset($session->id);
}
}

——————————————————————————
Product Attributes SQL Injection

http://svn.oscommerce.com/trac/changeset/703

——————————————————————————

Cambio 4:

Reemplazar en catalog/includes/classes/shopping_cart.php:

Linea 84, de:

if (is_numeric($products_id) && is_numeric($qty)) {

a:

$attributes_pass_check = true;

if (is_array($attributes)) {
reset($attributes);
while (list($option, $value) = each($attributes)) {
if (!is_numeric($option) || !is_numeric($value)) {
$attributes_pass_check = false;
break;
}
}
}

if (is_numeric($products_id) && is_numeric($qty) && ($attributes_pass_check == true)) {

Linea 125, de:

if (is_numeric($products_id) && isset($this->contents[$products_id_string]) && is_numeric($quantity)) {

a:

$attributes_pass_check = true;

if (is_array($attributes)) {
reset($attributes);
while (list($option, $value) = each($attributes)) {
if (!is_numeric($option) || !is_numeric($value)) {
$attributes_pass_check = false;
break;
}
}
}

if (is_numeric($products_id) && isset($this->contents[$products_id_string]) && is_numeric($quantity) && ($attributes_pass_check == true)) {

Reemplazar en catalog/shopping_cart.php:

Lineas 84-85, de:

where pa.products_id = '" . $products[$i]['id'] . "'
and pa.options_id = '" . $option . "'

a:

where pa.products_id = '" . (int)$products[$i]['id'] . "'
and pa.options_id = '" . (int)$option . "'

Line 87, de:

and pa.options_values_id = '" . $value . "'

a:

and pa.options_values_id = '" . (int)$value . "'

Lines 89-90, de:

and popt.language_id = '" . $languages_id . "'
and poval.language_id = '" . $languages_id . "'");

a:

and popt.language_id = '" . (int)$languages_id . "'
and poval.language_id = '" . (int)$languages_id . "'");

——————————————————————————
Resize Images To Round Numbers

http://www.oscommerce.com/community/bugs,1371

http://svn.oscommerce.com/trac/changeset/707

——————————————————————————

Cambio 5:
Reemplazar en catalog/includes/functions/html_output.php:

Line 91, de:

$width = $image_size[0] * $ratio;

a:

$width = intval($image_size[0] * $ratio);

Line 94, de:

$height = $image_size[1] * $ratio;

a:

$height = intval($image_size[1] * $ratio);

——————————————————————————
Use The Correct Country Name Value When Formatting Addresses

http://www.oscommerce.com/community/bugs,1291

http://svn.oscommerce.com/trac/changeset/713

——————————————————————————

Cambio 6:

Reemplazar en catalog/includes/functions/general.php:

Line 453, de:

$country = tep_output_string_protected($address['country']);

a:

$country = tep_output_string_protected($address['country']['title']);

La siguiente linea debe ser borrada:

Line 483:

if ($country == '') $country = tep_output_string_protected($address['country']);

——————————————————————————
Prevent The Session ID Being Passed In Tell-A-Friend E-Mails

http://www.oscommerce.com/community/bugs,3986

http://svn.oscommerce.com/trac/changeset/715

——————————————————————————

Cambio 7:

Reemplazar en catalog/tell_a_friend.php:

Linea 77, de:

$email_body .= sprintf(TEXT_EMAIL_LINK, tep_href_link(FILENAME_PRODUCT_INFO, 'products_id=' . $HTTP_GET_VARS['products_id'])) . "\n\n" .

a:

$email_body .= sprintf(TEXT_EMAIL_LINK, tep_href_link(FILENAME_PRODUCT_INFO, 'products_id=' . $HTTP_GET_VARS['products_id'], 'NONSSL', false)) . "\n\n" .

——————————————————————————
Properly Remove Deleted Products That Exist In Shopping Carts

http://www.oscommerce.com/community/bugs,3193

http://svn.oscommerce.com/trac/changeset/717

——————————————————————————

Cambio 8:

Reemplazar en catalog/admin/includes/functions/general.php:

Lines 900-901, de:

tep_db_query("delete from " . TABLE_CUSTOMERS_BASKET . " where products_id = '" . (int)$product_id . "'");
tep_db_query("delete from " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " where products_id = '" . (int)$product_id . "'");

a:

tep_db_query("delete from " . TABLE_CUSTOMERS_BASKET . " where products_id = '" . (int)$product_id . "' or products_id like '" . (int)$product_id . "{%'");
tep_db_query("delete from " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " where products_id = '" . (int)$product_id . "' or products_id like '" . (int)$product_id . "{%'");

Crea tus botones para Oscommerce

Lunes, 27 de Marzo de 2006

Si necesitas crear tus propios botones para OsCommerce, existe una página que puede ayudarte mucho y muy fácilmente

Osc Buttons

Elige tu color, el fondo, el idioma… Gran ayuda para personalizar tu tienda on-line

Selección.. Spain

Domingo, 29 de Enero de 2006

Una pequeña mejora para la creación de una nueva cuenta de usuario.

Este ejemplo sirve para España (Spain) , y lo que hace es seleccionar Spain directamente en el formulario, en vez del Seleccione. Es para aquella gente que suele vender en territorio nacional principalmente, aunque cambiando el código, puedes poner el país que desees. 195 para Spain

Editar create_account y busca..

' . ENTRY_COUNTRY_TEXT . '': ''); ?>

y cámbialo por:

' . ENTRY_COUNTRY_TEXT . '': ''); ?>

Lo que se añade es el ‘195′ indicando así España, digo Spain…

QFACWIN . Software de gestión orientado a OsCommerce

Miércoles, 18 de Enero de 2006

QFACWIN es el software de gestión ideal para tu empresa, comercio o actividad profesional.

Te permite gestionar rápida y eficazmente pedidos, albaranes, facturas, compras, gastos, impuestos, vendedores, artículos, servicios, almacén, clientes, presuntos clientes, proveedores, cobros, remesas bancarias, promociones, etc.

Además de tener acceso inmediato a tus datos, con QFACWIN puedes generar al momento estadísticas, gráficas de ventas y listados, etiquetas, cartas y fichas configurados con la información que necesites y editarlos con Word o Excel. Puedes personalizar tus impresos: facturas, albaranes, pedidos y recibos con el diseñador de formularios.

Con todas estas prestaciones, QFACWIN te sorprenderá porque es muy fácil de utilizar. El programa y toda la documentación están en español y dispone de parámetros de configuración para adaptarlo a la terminología y peculiaridades de cada país.

Pruebalo ahora gratuitamente y por tiempo ilimitado pulsando aquí

Además, TRASPASO A OSCOMMERCE es el programa que traspasa los datos de los artículos y categorías (descripciones, precios, existencias, fotografías, etc.) del programa de facturación QFACWIN a la tienda virtual osCommerce llenando la tienda automáticamente.

Revisión 051113 de OsCommerce

Viernes, 2 de Diciembre de 2005

Listado de los arreglos realizados en esta nueva versión de OsCommerce

  • 1/ customer_country_id en addressbook
  • Cuando el cliente actualiza su direccion en la pagina de Mi cuenta, el valor del pais esta guardada en una variable incorrecta que puede causar un valor de impuesto incorrecto usado en el precio de los productos.

    Solución:
    Las siguientes lineas deben ser reemplazadas en catalog/address_book_process.php:

    Linea 150, de:

    $customer_country_id = $country_id;

    a:

    $customer_country_id = $country;

    Linea 171, de:

    $customer_country_id = $country_id;

    a:

    $customer_country_id = $country;

  • 2/ Cannot re-assign $this
  • Fatal error: Cannot re-assign $this in /path/to/catalog/admin/includes/classes/upload.php on line 31

    Solución:

    Lineas 27-34 en catalog/admin/includes/classes/upload.php cambiar:

    if ( ($this->parse() == true) && ($this->save() == true) ) {
    return true;
    } else {
    // self destruct
    $this = null;

    return false;
    }

    a:

    if ( ($this->parse() == true) && ($this->save() == true) ) {
    return true;
    } else {
    return false;
    }

  • 3/ limit -20, 20
  • 1064 – You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘-20, 20′ at line 1

    Solución:

    Linea 67 en catalog/includes/classes/split_page_results.php, cambiar:

    $this->sql_query .= " limit " . $offset . ", " . $this->number_of_rows_per_page;
    a:

    $this->sql_query .= " limit " . max($offset, 0) . ", " . $this->number_of_rows_per_page;

    Linea 38 en catalog/admin/includes/classes/split_page_results.php, cambiar:

    $sql_query .= " limit " . $offset . ", " . $max_rows_per_page;

    a:

    $sql_query .= " limit " . max($offset, 0) . ", " . $max_rows_per_page;

  • 4/ Cambio en el Input de la Base de Datos
  • Problema:

    Funciones de MySQL deben ser usadas con prioridad a la funcion addslashes(), para proteger debidamente los queries SQL en el servidor de base de datos.

    Solución:

    La siguiente función debe ser reemplazada en catalog/includes/functions/database.php.

    Lineas 126-128, de:

    function tep_db_input($string) {
    return addslashes($string);
    }

    a:

    function tep_db_input($string, $link = 'db_link') {
    global $$link;

    if (function_exists('mysql_real_escape_string')) {
    return mysql_real_escape_string($string, $$link);
    } elseif (function_exists('mysql_escape_string')) {
    return mysql_escape_string($string);
    }

    return addslashes($string);
    }

    La siguiente funcion debe ser reemplazada en catalog/admin/includes/functions/database.php.

    Lineas 130-132, de:

    function tep_db_input($string) {
    return addslashes($string);
    }

    a:

    function tep_db_input($string, $link = 'db_link') {
    global $$link;

    if (function_exists('mysql_real_escape_string')) {
    return mysql_real_escape_string($string, $$link);
    } elseif (function_exists('mysql_escape_string')) {
    return mysql_escape_string($string);
    }

    return addslashes($string);
    }

  • 5/ Agregar Productos inexistentes a la cesta
  • Es posible agregar un producto inexistente a la cesta que puede impedir que los clientes lo borren de sus productos en la cesta.

    Solución:

    Las siguiente funciones deben ser reemplazadas en catalog/includes/functions/general.php.

    Lineas 912-921, de:

    function tep_get_uprid($prid, $params) {
    $uprid = $prid;
    if ( (is_array($params)) && (!strstr($prid, '{')) ) {
    while (list($option, $value) = each($params)) {
    $uprid = $uprid . '{' . $option . '}' . $value;
    }
    }

    return $uprid;
    }

    a:

    function tep_get_uprid($prid, $params) {
    if (is_numeric($prid)) {
    $uprid = $prid;

    if (is_array($params) && (sizeof($params) > 0)) {
    $attributes_check = true;
    $attributes_ids = '';

    reset($params);
    while (list($option, $value) = each($params)) {
    if (is_numeric($option) && is_numeric($value)) {
    $attributes_ids .= '{' . (int)$option . '}' . (int)$value;
    } else {
    $attributes_check = false;
    break;
    }
    }

    if ($attributes_check == true) {
    $uprid .= $attributes_ids;
    }
    }
    } else {
    $uprid = tep_get_prid($prid);

    if (is_numeric($uprid)) {
    if (strpos($prid, '{') !== false) {
    $attributes_check = true;
    $attributes_ids = '';

    // strpos()+1 to remove up to and including the first { which would create an empty array element in explode()
    $attributes = explode('{', substr($prid, strpos($prid, '{')+1));

    for ($i=0, $n=sizeof($attributes); $i<$n; $i++) {
    $pair = explode('}', $attributes[$i]);

    if (is_numeric($pair[0]) && is_numeric($pair[1])) {
    $attributes_ids .= '{' . (int)$pair[0] . '}' . (int)$pair[1];
    } else {
    $attributes_check = false;
    break;
    }
    }

    if ($attributes_check == true) {
    $uprid .= $attributes_ids;
    }
    }
    } else {
    return false;
    }
    }

    return $uprid;
    }

    Lineas 925-929, de:

    function tep_get_prid($uprid) {
    $pieces = explode('{', $uprid);

    return $pieces[0];
    }

    a:

    function tep_get_prid($uprid) {
    $pieces = explode('{', $uprid);

    if (is_numeric($pieces[0])) {
    return $pieces[0];
    } else {
    return false;
    }
    }

    Las siguientes funciones deben ser reemplazadas en catalog/includes/classes/shopping_cart.php.

    Lineas 78-108, de:

    function add_cart($products_id, $qty = '1', $attributes = '', $notify = true) {
    global $new_products_id_in_cart, $customer_id;

    $products_id = tep_get_uprid($products_id, $attributes);
    if ($notify == true) {
    $new_products_id_in_cart = $products_id;
    tep_session_register('new_products_id_in_cart');
    }

    if ($this->in_cart($products_id)) {
    $this->update_quantity($products_id, $qty, $attributes);
    } else {
    $this->contents[] = array($products_id);
    $this->contents[$products_id] = array('qty' => $qty);
    // insert into database
    if (tep_session_is_registered('customer_id')) tep_db_query("insert into " . TABLE_CUSTOMERS_BASKET . " (customers_id, products_id, customers_basket_quantity, customers_basket_date_added) values ('" . (int)$customer_id . "', '" . tep_db_input($products_id) . "', '" . $qty . "', '" . date('Ymd') . "')");

    if (is_array($attributes)) {
    reset($attributes);
    while (list($option, $value) = each($attributes)) {
    $this->contents[$products_id]['attributes'][$option] = $value;
    // insert into database
    if (tep_session_is_registered('customer_id')) tep_db_query("insert into " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " (customers_id, products_id, products_options_id, products_options_value_id) values ('" . (int)$customer_id . "', '" . tep_db_input($products_id) . "', '" . (int)$option . "', '" . (int)$value . "')");
    }
    }
    }
    $this->cleanup();

    // assign a temporary unique ID to the order contents to prevent hack attempts during the checkout procedure
    $this->cartID = $this->generate_cart_id();
    }

    a:

    function add_cart($products_id, $qty = '1', $attributes = '', $notify = true) {
    global $new_products_id_in_cart, $customer_id;

    $products_id_string = tep_get_uprid($products_id, $attributes);
    $products_id = tep_get_prid($products_id_string);

    if (is_numeric($products_id) && is_numeric($qty)) {
    $check_product_query = tep_db_query("select products_status from " . TABLE_PRODUCTS . " where products_id = '" . (int)$products_id . "'");
    $check_product = tep_db_fetch_array($check_product_query);

    if (($check_product !== false) && ($check_product['products_status'] == '1')) {
    if ($notify == true) {
    $new_products_id_in_cart = $products_id;
    tep_session_register('new_products_id_in_cart');
    }

    if ($this->in_cart($products_id_string)) {
    $this->update_quantity($products_id_string, $qty, $attributes);
    } else {
    $this->contents[$products_id_string] = array('qty' => $qty);
    // insert into database
    if (tep_session_is_registered('customer_id')) tep_db_query("insert into " . TABLE_CUSTOMERS_BASKET . " (customers_id, products_id, customers_basket_quantity, customers_basket_date_added) values ('" . (int)$customer_id . "', '" . tep_db_input($products_id_string) . "', '" . (int)$qty . "', '" . date('Ymd') . "')");

    if (is_array($attributes)) {
    reset($attributes);
    while (list($option, $value) = each($attributes)) {
    $this->contents[$products_id_string]['attributes'][$option] = $value;
    // insert into database
    if (tep_session_is_registered('customer_id')) tep_db_query("insert into " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " (customers_id, products_id, products_options_id, products_options_value_id) values ('" . (int)$customer_id . "', '" . tep_db_input($products_id_string) . "', '" . (int)$option . "', '" . (int)$value . "')");
    }
    }
    }

    $this->cleanup();

    // assign a temporary unique ID to the order contents to prevent hack attempts during the checkout procedure
    $this->cartID = $this->generate_cart_id();
    }
    }
    }

    Lineas 110-127, de:

    function update_quantity($products_id, $quantity = '', $attributes = '') {
    global $customer_id;

    if (empty($quantity)) return true; // nothing needs to be updated if theres no quantity, so we return true..

    $this->contents[$products_id] = array('qty' => $quantity);
    // update database
    if (tep_session_is_registered('customer_id')) tep_db_query("update " . TABLE_CUSTOMERS_BASKET . " set customers_basket_quantity = '" . $quantity . "' where customers_id = '" . (int)$customer_id . "' and products_id = '" . tep_db_input($products_id) . "'");

    if (is_array($attributes)) {
    reset($attributes);
    while (list($option, $value) = each($attributes)) {
    $this->contents[$products_id]['attributes'][$option] = $value;
    // update database
    if (tep_session_is_registered('customer_id')) tep_db_query("update " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " set products_options_value_id = '" . (int)$value . "' where customers_id = '" . (int)$customer_id . "' and products_id = '" . tep_db_input($products_id) . "' and products_options_id = '" . (int)$option . "'");
    }
    }
    }

    a:

    function update_quantity($products_id, $quantity = '', $attributes = '') {
    global $customer_id;

    $products_id_string = tep_get_uprid($products_id, $attributes);
    $products_id = tep_get_prid($products_id_string);

    if (is_numeric($products_id) && isset($this->contents[$products_id_string]) && is_numeric($quantity)) {
    $this->contents[$products_id_string] = array('qty' => $quantity);
    // update database
    if (tep_session_is_registered('customer_id')) tep_db_query("update " . TABLE_CUSTOMERS_BASKET . " set customers_basket_quantity = '" . (int)$quantity . "' where customers_id = '" . (int)$customer_id . "' and products_id = '" . tep_db_input($products_id_string) . "'");

    if (is_array($attributes)) {
    reset($attributes);
    while (list($option, $value) = each($attributes)) {
    $this->contents[$products_id_string]['attributes'][$option] = $value;
    // update database
    if (tep_session_is_registered('customer_id')) tep_db_query("update " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " set products_options_value_id = '" . (int)$value . "' where customers_id = '" . (int)$customer_id . "' and products_id = '" . tep_db_input($products_id_string) . "' and products_options_id = '" . (int)$option . "'");
    }
    }
    }
    }

  • 6/ El Tema de Session ID XSS
  • El tema de cross site scripting existente con la mal formada session IDs usado en la funcion tep_href_link().

    Solución:

    Linea 66 ein catalog/includes/functions/html_output.php debe ser cambiada de:

    $link .= $separator . $_sid;

    a:

    $link .= $separator . tep_output_string($_sid);

  • 7/ Validar Session ID
  • Validar session ID y redireccionar a la portada cuando la una session ID invalida es llamada.

    Solución:

    La siguiente función debe ser reemplazada en catalog/includes/functions/sessions.php.

    Lineas 66-68, de:

    function tep_session_start() {
    return session_start();
    }

    a:

    function tep_session_start() {
    global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS;

    $sane_session_id = true;

    if (isset($HTTP_GET_VARS[tep_session_name()])) {
    if (preg_match('/^[a-zA-Z0-9]+$/', $HTTP_GET_VARS[tep_session_name()]) == false) {
    unset($HTTP_GET_VARS[tep_session_name()]);

    $sane_session_id = false;
    }
    } elseif (isset($HTTP_POST_VARS[tep_session_name()])) {
    if (preg_match('/^[a-zA-Z0-9]+$/', $HTTP_POST_VARS[tep_session_name()]) == false) {
    unset($HTTP_POST_VARS[tep_session_name()]);

    $sane_session_id = false;
    }
    } elseif (isset($HTTP_COOKIE_VARS[tep_session_name()])) {
    if (preg_match('/^[a-zA-Z0-9]+$/', $HTTP_COOKIE_VARS[tep_session_name()]) == false) {
    $session_data = session_get_cookie_params();

    setcookie(tep_session_name(), '', time()-42000, $session_data['path'], $session_data['domain']);

    $sane_session_id = false;
    }
    }

    if ($sane_session_id == false) {
    tep_redirect(tep_href_link(FILENAME_DEFAULT, '', 'NONSSL', false));
    }

    return session_start();
    }

  • 8/ Problema en la Herramienta de Ficheros
  • Errores de Parsing generan cuando salvas ficheros editados con la herramienta ficheros:

    Linea 148 en catalog/admin/file_manager.php cambiar

    $file_contents = htmlspecialchars(implode('', $file_array));

    a:

    $file_contents = addslashes(implode('', $file_array));

    Nota: Esta actualización requiere la actualización de El tema de XSS en el formulario Contactenos para funcionar debidamente.

  • 9/ Inyección en la Cabecera HTTP
  • Usando datos malintencionados pueden hacer inyecciones de cabecera a los HTTP requests.

    Solución:

    La siguiente funcion debe ser reemplazada en catalog/includes/functions/general.php.

    Lineas 22-32, de:

    function tep_redirect($url) {
    if ( (ENABLE_SSL == true) && (getenv('HTTPS') == 'on') ) { // We are loading an SSL page
    if (substr($url, 0, strlen(HTTP_SERVER)) == HTTP_SERVER) { // NONSSL url
    $url = HTTPS_SERVER . substr($url, strlen(HTTP_SERVER)); // Change it to SSL
    }
    }

    header('Location: ' . $url);

    tep_exit();
    }

    a:

    function tep_redirect($url) {
    if ( (strstr($url, "\n") != false) || (strstr($url, "\r") != false) ) {
    tep_redirect(tep_href_link(FILENAME_DEFAULT, '', 'NONSSL', false));
    }

    if ( (ENABLE_SSL == true) && (getenv('HTTPS') == 'on') ) { // We are loading an SSL page
    if (substr($url, 0, strlen(HTTP_SERVER)) == HTTP_SERVER) { // NONSSL url
    $url = HTTPS_SERVER . substr($url, strlen(HTTP_SERVER)); // Change it to SSL
    }
    }

    header('Location: ' . $url);

    tep_exit();
    }

    La siguiente funcion debe ser reemplazada en catalog/admin/includes/functions/general.php.

    Lineas 15-26, de:

    function tep_redirect($url) {
    global $logger;

    header('Location: ' . $url);

    if (STORE_PAGE_PARSE_TIME == 'true') {
    if (!is_object($logger)) $logger = new logger;
    $logger->timer_stop();
    }

    exit;
    }

    a:

    function tep_redirect($url) {
    global $logger;

    if ( (strstr($url, "\n") != false) || (strstr($url, "\r") != false) ) {
    tep_redirect(tep_href_link(FILENAME_DEFAULT, '', 'NONSSL', false));
    }

    header('Location: ' . $url);

    if (STORE_PAGE_PARSE_TIME == 'true') {
    if (!is_object($logger)) $logger = new logger;
    $logger->timer_stop();
    }

    exit;
    }

  • 10/ Inyeccion en la Cabecera de E-Mail Header
  • Usando datos malintencionados pueden hacer inyecciones de cabecera en los correos que envia el administrador de la tienda.

    Solución:

    La siguiente funcion debe ser reemplazada en catalog/includes/classes/email.php and catalog/admin/includes/classes/email.php.

    Lineas 473-504, de:

    function send($to_name, $to_addr, $from_name, $from_addr, $subject = '', $headers = '') {
    $to = (($to_name != '') ? '"' . $to_name . '" <' . $to_addr . '>' : $to_addr);
    $from = (($from_name != '') ? '"' . $from_name . '" <' . $from_addr . '>' : $from_addr);

    if (is_string($headers)) {
    $headers = explode($this->lf, trim($headers));
    }

    for ($i=0; $i if (is_array($headers[$i])) {
    for ($j=0; $j if ($headers[$i][$j] != '') {
    $xtra_headers[] = $headers[$i][$j];
    }
    }
    }

    if ($headers[$i] != '') {
    $xtra_headers[] = $headers[$i];
    }
    }

    if (!isset($xtra_headers)) {
    $xtra_headers = array();
    }

    if (EMAIL_TRANSPORT == 'smtp') {
    return mail($to_addr, $subject, $this->output, 'From: ' . $from . $this->lf . 'To: ' . $to . $this->lf . implode($this->lf, $this->headers) . $this->lf . implode($this->lf, $xtra_headers));
    } else {
    return mail($to, $subject, $this->output, 'From: '.$from.$this->lf.implode($this->lf, $this->headers).$this->lf.implode($this->lf, $xtra_headers));
    }
    }

    a:

    function send($to_name, $to_addr, $from_name, $from_addr, $subject = '', $headers = '') {
    if ((strstr($to_name, "\n") != false) || (strstr($to_name, "\r") != false)) {
    return false;
    }

    if ((strstr($to_addr, "\n") != false) || (strstr($to_addr, "\r") != false)) {
    return false;
    }

    if ((strstr($subject, "\n") != false) || (strstr($subject, "\r") != false)) {
    return false;
    }

    if ((strstr($from_name, "\n") != false) || (strstr($from_name, "\r") != false)) {
    return false;
    }

    if ((strstr($from_addr, "\n") != false) || (strstr($from_addr, "\r") != false)) {
    return false;
    }

    $to = (($to_name != '') ? '"' . $to_name . '" <' . $to_addr . '>' : $to_addr);
    $from = (($from_name != '') ? '"' . $from_name . '" <' . $from_addr . '>' : $from_addr);

    if (is_string($headers)) {
    $headers = explode($this->lf, trim($headers));
    }

    for ($i=0; $i if (is_array($headers[$i])) {
    for ($j=0; $j if ($headers[$i][$j] != '') {
    $xtra_headers[] = $headers[$i][$j];
    }
    }
    }

    if ($headers[$i] != '') {
    $xtra_headers[] = $headers[$i];
    }
    }

    if (!isset($xtra_headers)) {
    $xtra_headers = array();
    }

    if (EMAIL_TRANSPORT == 'smtp') {
    return mail($to_addr, $subject, $this->output, 'From: ' . $from . $this->lf . 'To: ' . $to . $this->lf . implode($this->lf, $this->headers) . $this->lf . implode($this->lf, $xtra_headers));
    } else {
    return mail($to, $subject, $this->output, 'From: '.$from.$this->lf.implode($this->lf, $this->headers).$this->lf.implode($this->lf, $xtra_headers));
    }
    }

  • 11/El tema de XSS en el formulario Contactenos
  • Usando datos malintencionados es posible inyecctar HTML en la pagina.

    Solución:

    Lineas 221-225 in catalog/includes/functions/html_output.php cambiar:

    if ( (isset($GLOBALS[$name])) && ($reinsert_value == true) ) {
    $field .= stripslashes($GLOBALS[$name]);
    } elseif (tep_not_null($text)) {
    $field .= $text;
    }

    a:

    if ( (isset($GLOBALS[$name])) && ($reinsert_value == true) ) {
    $field .= tep_output_string_protected(stripslashes($GLOBALS[$name]));
    } elseif (tep_not_null($text)) {
    $field .= tep_output_string_protected($text);
    }

    Lineas 244-248 in catalog/admin/includes/functions/html_output.php cambiar:

    if ( (isset($GLOBALS[$name])) && ($reinsert_value == true) ) {
    $field .= stripslashes($GLOBALS[$name]);
    } elseif (tep_not_null($text)) {
    $field .= $text;
    }

    a:

    if ( (isset($GLOBALS[$name])) && ($reinsert_value == true) ) {
    $field .= tep_output_string_protected(stripslashes($GLOBALS[$name]));
    } elseif (tep_not_null($text)) {
    $field .= tep_output_string_protected($text);
    }

  • 12/ Redireccionamiento Abierto
  • No existe ningún chequeo en la página de redirección, y permite fuentes externas usar la página como un redireccionamiento abierto.

    Solución:

    Lineas 27-29 in catalog/redirect.php cambiar:

    if (isset($HTTP_GET_VARS['goto']) && tep_not_null($HTTP_GET_VARS['goto'])) {
    tep_redirect('http://' . $HTTP_GET_VARS['goto']);
    }

    a:

    if (isset($HTTP_GET_VARS['goto']) && tep_not_null($HTTP_GET_VARS['goto'])) {
    $check_query = tep_db_query("select products_url from " . TABLE_PRODUCTS_DESCRIPTION . " where products_url = '" . tep_db_input($HTTP_GET_VARS['goto']) . "' limit 1");
    if (tep_db_num_rows($check_query)) {
    tep_redirect('http://' . $HTTP_GET_VARS['goto']);
    }
    }

  • 13/ Barras Extras en Nuevos Productos
  • Cuando creas y producto, y previsualizas, al volver generaba unos errores con las barras

    Solución:

    Las siguientes lineas deben ser cambiadas en catalog/admin/categories.php:

    Linea 504, de:

    products_id, $languages[$i]['id']))); ?>

    a:

    products_id, $languages[$i]['id']))); ?>

    Linea 538, de:

    products_id, $languages[$i]['id']))); ?>

    a:

    products_id, $languages[$i]['id']))); ?>

    Linea 574, de:

    products_id, $languages[$i]['id']))); ?>

    a:

    products_id, $languages[$i]['id']))); ?>

  • 14/ Filtrando el Estado de Pedido
  • Después de cambiar el filtro de estado de pedidos en Administración -> Clientes -> Pedidos, seleccionando "Todos los Pedidos" mostrara una lista vacia de pedidos.

    Solución:

    Linea 357 in catalog/admin/orders.php cambiar:

    } elseif (isset($HTTP_GET_VARS['status'])) {

    a:

    } elseif (isset($HTTP_GET_VARS['status']) && is_numeric($HTTP_GET_VARS['status']) && ($HTTP_GET_VARS['status'] > 0)) {

  • 15/ Compatibilidad con MySQL 5.0
  • Hay ciertos queries de MySQL que no son compatibles y por lo tanto, no se pueden ejecutar en MySQL5.

    Solución:

    Linea 213-223 en catalog/advanced_search_result.php cambiar:

    $from_str = "from " . TABLE_PRODUCTS . " p left join " . TABLE_MANUFACTURERS . " m using(manufacturers_id) left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id, " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_CATEGORIES . " c, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c";

    if ( (DISPLAY_PRICE_WITH_TAX == 'true') && (tep_not_null($pfrom) || tep_not_null($pto)) ) {
    if (!tep_session_is_registered('customer_country_id')) {
    $customer_country_id = STORE_COUNTRY;
    $customer_zone_id = STORE_ZONE;
    }
    $from_str .= " left join " . TABLE_TAX_RATES . " tr on p.products_tax_class_id = tr.tax_class_id left join " . TABLE_ZONES_TO_GEO_ZONES . " gz on tr.tax_zone_id = gz.geo_zone_id and (gz.zone_country_id is null or gz.zone_country_id = '0' or gz.zone_country_id = '" . (int)$customer_country_id . "') and (gz.zone_id is null or gz.zone_id = '0' or gz.zone_id = '" . (int)$customer_zone_id . "')";
    }

    $where_str = " where p.products_status = '1' and p.products_id = pd.products_id and pd.language_id = '" . (int)$languages_id . "' and p.products_id = p2c.products_id and p2c.categories_id = c.categories_id ";

    a:

    $from_str = "from " . TABLE_PRODUCTS . " p left join " . TABLE_MANUFACTURERS . " m using(manufacturers_id) left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id";

    if ( (DISPLAY_PRICE_WITH_TAX == 'true') && (tep_not_null($pfrom) || tep_not_null($pto)) ) {
    if (!tep_session_is_registered('customer_country_id')) {
    $customer_country_id = STORE_COUNTRY;
    $customer_zone_id = STORE_ZONE;
    }
    $from_str .= " left join " . TABLE_TAX_RATES . " tr on p.products_tax_class_id = tr.tax_class_id left join " . TABLE_ZONES_TO_GEO_ZONES . " gz on tr.tax_zone_id = gz.geo_zone_id and (gz.zone_country_id is null or gz.zone_country_id = '0' or gz.zone_country_id = '" . (int)$customer_country_id . "') and (gz.zone_id is null or gz.zone_id = '0' or gz.zone_id = '" . (int)$customer_zone_id . "')";
    }

    $from_str .= ", " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_CATEGORIES . " c, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c";

    $where_str = " where p.products_status = '1' and p.products_id = pd.products_id and pd.language_id = '" . (int)$languages_id . "' and p.products_id = p2c.products_id and p2c.categories_id = c.categories_id ";

    Lsa siguientes lineas deben ser cambiadas en catalog/index.php:

    Linea 175, de:

    $listing_sql = "select " . $select_column_list . " p.products_id, p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status, s.specials_new_products_price, NULL) as specials_new_products_price, IF(s.status, s.specials_new_products_price, p.products_price) as final_price from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_MANUFACTURERS . " m, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id where p.products_status = '1' and p.manufacturers_id = m.manufacturers_id and m.manufacturers_id = '" . (int)$HTTP_GET_VARS['manufacturers_id'] . "' and p.products_id = p2c.products_id and pd.products_id = p2c.products_id and pd.language_id = '" . (int)$languages_id . "' and p2c.categories_id = '" . (int)$HTTP_GET_VARS['filter_id'] . "'";

    a:

    $listing_sql = "select " . $select_column_list . " p.products_id, p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status, s.specials_new_products_price, NULL) as specials_new_products_price, IF(s.status, s.specials_new_products_price, p.products_price) as final_price from " . TABLE_PRODUCTS . " p left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id, " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_MANUFACTURERS . " m, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c where p.products_status = '1' and p.manufacturers_id = m.manufacturers_id and m.manufacturers_id = '" . (int)$HTTP_GET_VARS['manufacturers_id'] . "' and p.products_id = p2c.products_id and pd.products_id = p2c.products_id and pd.language_id = '" . (int)$languages_id . "' and p2c.categories_id = '" . (int)$HTTP_GET_VARS['filter_id'] . "'";

    Linea 178, de:

    $listing_sql = "select " . $select_column_list . " p.products_id, p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status, s.specials_new_products_price, NULL) as specials_new_products_price, IF(s.status, s.specials_new_products_price, p.products_price) as final_price from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_MANUFACTURERS . " m left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id where p.products_status = '1' and pd.products_id = p.products_id and pd.language_id = '" . (int)$languages_id . "' and p.manufacturers_id = m.manufacturers_id and m.manufacturers_id = '" . (int)$HTTP_GET_VARS['manufacturers_id'] . "'";

    a:

    $listing_sql = "select " . $select_column_list . " p.products_id, p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status, s.specials_new_products_price, NULL) as specials_new_products_price, IF(s.status, s.specials_new_products_price, p.products_price) as final_price from " . TABLE_PRODUCTS . " p left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id, " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_MANUFACTURERS . " m where p.products_status = '1' and pd.products_id = p.products_id and pd.language_id = '" . (int)$languages_id . "' and p.manufacturers_id = m.manufacturers_id and m.manufacturers_id = '" . (int)$HTTP_GET_VARS['manufacturers_id'] . "'";

    Linea 184, de:

    $listing_sql = "select " . $select_column_list . " p.products_id, p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status, s.specials_new_products_price, NULL) as specials_new_products_price, IF(s.status, s.specials_new_products_price, p.products_price) as final_price from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_MANUFACTURERS . " m, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id where p.products_status = '1' and p.manufacturers_id = m.manufacturers_id and m.manufacturers_id = '" . (int)$HTTP_GET_VARS['filter_id'] . "' and p.products_id = p2c.products_id and pd.products_id = p2c.products_id and pd.language_id = '" . (int)$languages_id . "' and p2c.categories_id = '" . (int)$current_category_id . "'";

    a:

    $listing_sql = "select " . $select_column_list . " p.products_id, p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status, s.specials_new_products_price, NULL) as specials_new_products_price, IF(s.status, s.specials_new_products_price, p.products_price) as final_price from " . TABLE_PRODUCTS . " p left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id, " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_MANUFACTURERS . " m, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c where p.products_status = '1' and p.manufacturers_id = m.manufacturers_id and m.manufacturers_id = '" . (int)$HTTP_GET_VARS['filter_id'] . "' and p.products_id = p2c.products_id and pd.products_id = p2c.products_id and pd.language_id = '" . (int)$languages_id . "' and p2c.categories_id = '" . (int)$current_category_id . "'";

    Linea 187, de:

    $listing_sql = "select " . $select_column_list . " p.products_id, p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status, s.specials_new_products_price, NULL) as specials_new_products_price, IF(s.status, s.specials_new_products_price, p.products_price) as final_price from " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_PRODUCTS . " p left join " . TABLE_MANUFACTURERS . " m on p.manufacturers_id = m.manufacturers_id, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id where p.products_status = '1' and p.products_id = p2c.products_id and pd.products_id = p2c.products_id and pd.language_id = '" . (int)$languages_id . "' and p2c.categories_id = '" . (int)$current_category_id . "'";

    a:

    $listing_sql = "select " . $select_column_list . " p.products_id, p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status, s.specials_new_products_price, NULL) as specials_new_products_price, IF(s.status, s.specials_new_products_price, p.products_price) as final_price from " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_PRODUCTS . " p left join " . TABLE_MANUFACTURERS . " m on p.manufacturers_id = m.manufacturers_id left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c where p.products_status = '1' and p.products_id = p2c.products_id and pd.products_id = p2c.products_id and pd.language_id = '" . (int)$languages_id . "' and p2c.categories_id = '" . (int)$current_category_id . "'";

    Linea 292 in catalog/admin/categories.php cambiar:

    tep_db_query("insert into " . TABLE_PRODUCTS . " (products_quantity, products_model,products_image, products_price, products_date_added, products_date_available, products_weight, products_status, products_tax_class_id, manufacturers_id) values ('" . tep_db_input($product['products_quantity']) . "', '" . tep_db_input($product['products_model']) . "', '" . tep_db_input($product['products_image']) . "', '" . tep_db_input($product['products_price']) . "', now(), '" . tep_db_input($product['products_date_available']) . "', '" . tep_db_input($product['products_weight']) . "', '0', '" . (int)$product['products_tax_class_id'] . "', '" . (int)$product['manufacturers_id'] . "')");
    a:

    tep_db_query("insert into " . TABLE_PRODUCTS . " (products_quantity, products_model,products_image, products_price, products_date_added, products_date_available, products_weight, products_status, products_tax_class_id, manufacturers_id) values ('" . tep_db_input($product['products_quantity']) . "', '" . tep_db_input($product['products_model']) . "', '" . tep_db_input($product['products_image']) . "', '" . tep_db_input($product['products_price']) . "', now(), " . (empty($product['products_date_available']) ? "null" : "'" . tep_db_input($product['products_date_available']) . "'") . ", '" . tep_db_input($product['products_weight']) . "', '0', '" . (int)$product['products_tax_class_id'] . "', '" . (int)$product['manufacturers_id'] . "')");

    Los siguientes comandos MySQL deben ser ejecutados:

    ALTER TABLE whos_online MODIFY COLUMN last_page_url VARCHAR(255) NOT NULL;

    ALTER TABLE customers MODIFY COLUMN customers_default_address_id INTEGER;

    ALTER TABLE customers_basket MODIFY COLUMN final_price DECIMAL(15,4);

    Vía SmartOsc