📋 OWASP Top 10 en PrestaShop — guia de referencia

Actualizado: 2024-12-01

El OWASP Top 10 es la referencia estandar de las 10 vulnerabilidades mas criticas. Esta guia la aplica especificamente al desarrollo de modulos y personalizaciones de PrestaShop.

#A01 — Broken Access Control

A01 — Verificar acceso antes de cada accion
php
<?php

// ❌ VULNERABLE — No verifica que el pedido pertenece al cliente
public function hookActionOrderDetail(array $params): void
{
    $idOrder = (int) Tools::getValue('id_order'); // Cualquiera puede pasar cualquier ID
    $order   = new Order($idOrder);
    $this->displayOrderData($order); // Expone pedidos de otros clientes
}

// ✅ CORRECTO — Siempre verificar la propiedad del recurso
public function hookActionOrderDetail(array $params): void
{
    $idOrder  = (int) Tools::getValue('id_order');
    $order    = new Order($idOrder);
    $customer = $this->context->customer;

    // Verificar que el pedido pertenece al cliente logueado
    if (!$customer->isLogged() || (int) $order->id_customer !== (int) $customer->id) {
        header('HTTP/1.1 403 Forbidden');
        exit();
    }

    $this->displayOrderData($order);
}

#A02 — Cryptographic Failures

A02 — Almacenamiento seguro de datos sensibles
php
<?php

// ❌ VULNERABLE — Datos sensibles sin cifrar
Configuration::updateValue('MYMODULE_API_SECRET', $apiSecret); // En texto plano en DB

// ✅ CORRECTO — Cifrar datos sensibles
// PrestaShop tiene Tools::encrypt() basado en la frase de seguridad
$encrypted = Tools::encrypt($apiSecret);
Configuration::updateValue('MYMODULE_API_SECRET', $encrypted);

// Para recuperar:
$decrypted = Tools::decrypt(Configuration::get('MYMODULE_API_SECRET'));

// ❌ VULNERABLE — MD5 para passwords (obsoleto)
$hash = md5($password); // MD5 es reversible con tablas rainbow

// ✅ CORRECTO — PS usa su propio sistema de hash
// NO implementar sistema de passwords propio
// Usar siempre el sistema de autenticacion de PS:
$customer->passwd = Tools::hash($password); // Hash seguro de PS

// ✅ Para tokens/secrets de un solo uso:
$token = bin2hex(random_bytes(32)); // 64 chars hex aleatorios

#A03 — Injection

Tipo de InjectionPrevencion en PS
SQL InjectionpSQL(), (int), (float), DbQuery builder
XSS (HTML/JS)htmlspecialchars(), Smarty escape, Twig auto-escape
Command InjectionNunca pasar input del usuario a exec()/shell_exec()
LDAP InjectionNo aplica en PS estandar
Path Traversalbasename(), realpath(), verificar que path esta dentro del directorio permitido
Object InjectionNunca unserialize() con datos del usuario; usar json_decode()

#A05 — Security Misconfiguration

ConfiguracionValor recomendado en produccion
_PS_MODE_DEV_false
Directorio /install/Eliminado tras la instalacion
display_errors PHPOff
Directorio /admin/Renombrado a nombre secreto
HTTPSForzado (PS_SSL_ENABLED=1)
Mensajes de error detalladosDesactivados en produccion
Archivos de configuracionFuera del webroot (config.inc.php)

#A07 — Authentication Failures

A07 — Buenas practicas de autenticacion
php
<?php

// ── NUNCA implementar autenticacion propia ──
// Usar siempre el sistema de PS:

// FO — verificar cliente
if (!$this->context->customer->isLogged()) {
    Tools::redirect($this->context->link->getPageLink('authentication'));
}

// BO — verificar empleado
if (!$this->context->employee->isLoggedBack()) {
    Tools::redirect($this->context->link->getAdminLink('AdminLogin'));
}

// ── Limitar intentos de login ──
// PS tiene proteccion basica contra brute force
// Para reforzar, usar un modulo de 2FA o ratelimiting

// ── Regenerar session ID despues de login ──
// PS lo hace automaticamente
// En modulos custom que usan Sessions:
if (session_status() === PHP_SESSION_ACTIVE) {
    session_regenerate_id(true); // Previene session fixation
}

// ── Timeout de sesion ──
// Configurado en Parametros Avanzados → Configuracion → Seguridad

#A09 — Logging Failures

A09 — Logging correcto de eventos de seguridad
php
<?php

// ── Loggear eventos de seguridad relevantes ──

// Intento de acceso no autorizado
PrestaShopLogger::addLog(
    'Unauthorized access attempt: ' . $_SERVER['REMOTE_ADDR'],
    3,   // Severity: 1=info, 2=warning, 3=error, 4=major
    403,
    'MyModule',
    0,
    true // Enviar email al admin
);

// Accion sensible completada
PrestaShopLogger::addLog(
    'API key regenerated by employee ' . $this->context->employee->id,
    1,
    null,
    'MyModule'
);

// ── NO loggear datos sensibles ──
// ❌ PrestaShopLogger::addLog('Password: ' . $password, ...);
// ❌ PrestaShopLogger::addLog('API Key: ' . $apiKey, ...);
// ✅ PrestaShopLogger::addLog('Login attempt for user: ' . $email, ...);

#Checklist de seguridad para modulos

ItemEstado
Todo input del usuario esta escapado con pSQL/(int)/(float)
Todos los templates usan |escape:'html' o Twig auto-escape
Formularios incluyen y verifican tokens CSRF
Uploads verifican MIME type real con finfo
Uploads usan nombres aleatorios (random_bytes)
Acciones verifican que el recurso pertenece al usuario
Empleados verifican isLoggedBack() y permisos de Tab
Datos sensibles cifrados con Tools::encrypt()
No se usa eval(), exec() con input del usuario
No se usa unserialize() con input del usuario
_PS_MODE_DEV_ = false en produccion
HTTPS forzado en toda la tienda
Descargar en Markdown Pensado para pegar en ChatGPT, Claude u otra IA. Incluye solo el contenido de esta pagina.