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));
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<count($headers); $i++) { if (is_array($headers[$i])) { for ($j=0; $j<count($headers[$i]); $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<count($headers); $i++) { if (is_array($headers[$i])) { for ($j=0; $j<count($headers[$i]); $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:
<td class="main"><?php echo tep_image(DIR_WS_CATALOG_LANGUAGES . $languages[$i]['directory'] . '/images/' . $languages[$i]['image'], $languages[$i]['name']) . ' ' . tep_draw_input_field('products_name[' . $languages[$i]['id'] . ']', (isset($products_name[$languages[$i]['id']]) ? $products_name[$languages[$i]['id']] : tep_get_products_name($pInfo->products_id, $languages[$i]['id']))); ?></td>
a:
<td class="main"><?php echo tep_image(DIR_WS_CATALOG_LANGUAGES . $languages[$i]['directory'] . '/images/' . $languages[$i]['image'], $languages[$i]['name']) . ' ' . tep_draw_input_field('products_name[' . $languages[$i]['id'] . ']', (isset($products_name[$languages[$i]['id']]) ? stripslashes($products_name[$languages[$i]['id']]) : tep_get_products_name($pInfo->products_id, $languages[$i]['id']))); ?></td>
Linea 538, de:
<td class="main"><?php echo tep_draw_textarea_field('products_description[' . $languages[$i]['id'] . ']', 'soft', '70', '15', (isset($products_description[$languages[$i]['id']]) ? $products_description[$languages[$i]['id']] : tep_get_products_description($pInfo->products_id, $languages[$i]['id']))); ?></td>
a:
<td class="main"><?php echo tep_draw_textarea_field('products_description[' . $languages[$i]['id'] . ']', 'soft', '70', '15', (isset($products_description[$languages[$i]['id']]) ? stripslashes($products_description[$languages[$i]['id']]) : tep_get_products_description($pInfo->products_id, $languages[$i]['id']))); ?></td>
Linea 574, de:
>td class="main">>?php echo tep_image(DIR_WS_CATALOG_LANGUAGES . $languages[$i]['directory'] . '/images/' . $languages[$i]['image'], $languages[$i]['name']) . ' ' . tep_draw_input_field('products_url[' . $languages[$i]['id'] . ']', (isset($products_url[$languages[$i]['id']]) ? $products_url[$languages[$i]['id']] : tep_get_products_url($pInfo->products_id, $languages[$i]['id']))); ?>>/td>
a:
<td class="main"><?php echo tep_image(DIR_WS_CATALOG_LANGUAGES . $languages[$i]['directory'] . '/images/' . $languages[$i]['image'], $languages[$i]['name']) . ' ' . tep_draw_input_field('products_url[' . $languages[$i]['id'] . ']', (isset($products_url[$languages[$i]['id']]) ? stripslashes($products_url[$languages[$i]['id']]) : tep_get_products_url($pInfo->products_id, $languages[$i]['id']))); ?></td>
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
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<count($headers); $i++) { if (is_array($headers[$i])) { for ($j=0; $j<count($headers[$i]); $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<count($headers); $i++) { if (is_array($headers[$i])) { for ($j=0; $j<count($headers[$i]); $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:
<td class="main"><?php echo tep_image(DIR_WS_CATALOG_LANGUAGES . $languages[$i]['directory'] . '/images/' . $languages[$i]['image'], $languages[$i]['name']) . ' ' . tep_draw_input_field('products_name[' . $languages[$i]['id'] . ']', (isset($products_name[$languages[$i]['id']]) ? $products_name[$languages[$i]['id']] : tep_get_products_name($pInfo->products_id, $languages[$i]['id']))); ?></td>
a:
<td class="main"><?php echo tep_image(DIR_WS_CATALOG_LANGUAGES . $languages[$i]['directory'] . '/images/' . $languages[$i]['image'], $languages[$i]['name']) . ' ' . tep_draw_input_field('products_name[' . $languages[$i]['id'] . ']', (isset($products_name[$languages[$i]['id']]) ? stripslashes($products_name[$languages[$i]['id']]) : tep_get_products_name($pInfo->products_id, $languages[$i]['id']))); ?></td>
Linea 538, de:
<td class="main"><?php echo tep_draw_textarea_field('products_description[' . $languages[$i]['id'] . ']', 'soft', '70', '15', (isset($products_description[$languages[$i]['id']]) ? $products_description[$languages[$i]['id']] : tep_get_products_description($pInfo->products_id, $languages[$i]['id']))); ?></td>
a:
<td class="main"><?php echo tep_draw_textarea_field('products_description[' . $languages[$i]['id'] . ']', 'soft', '70', '15', (isset($products_description[$languages[$i]['id']]) ? stripslashes($products_description[$languages[$i]['id']]) : tep_get_products_description($pInfo->products_id, $languages[$i]['id']))); ?></td>
Linea 574, de:
>td class="main">>?php echo tep_image(DIR_WS_CATALOG_LANGUAGES . $languages[$i]['directory'] . '/images/' . $languages[$i]['image'], $languages[$i]['name']) . ' ' . tep_draw_input_field('products_url[' . $languages[$i]['id'] . ']', (isset($products_url[$languages[$i]['id']]) ? $products_url[$languages[$i]['id']] : tep_get_products_url($pInfo->products_id, $languages[$i]['id']))); ?>>/td>
a:
<td class="main"><?php echo tep_image(DIR_WS_CATALOG_LANGUAGES . $languages[$i]['directory'] . '/images/' . $languages[$i]['image'], $languages[$i]['name']) . ' ' . tep_draw_input_field('products_url[' . $languages[$i]['id'] . ']', (isset($products_url[$languages[$i]['id']]) ? stripslashes($products_url[$languages[$i]['id']]) : tep_get_products_url($pInfo->products_id, $languages[$i]['id']))); ?></td>
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