📋 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 Injection | Prevencion en PS |
|---|---|
| SQL Injection | pSQL(), (int), (float), DbQuery builder |
| XSS (HTML/JS) | htmlspecialchars(), Smarty escape, Twig auto-escape |
| Command Injection | Nunca pasar input del usuario a exec()/shell_exec() |
| LDAP Injection | No aplica en PS estandar |
| Path Traversal | basename(), realpath(), verificar que path esta dentro del directorio permitido |
| Object Injection | Nunca unserialize() con datos del usuario; usar json_decode() |
#A05 — Security Misconfiguration
| Configuracion | Valor recomendado en produccion |
|---|---|
| _PS_MODE_DEV_ | false |
| Directorio /install/ | Eliminado tras la instalacion |
| display_errors PHP | Off |
| Directorio /admin/ | Renombrado a nombre secreto |
| HTTPS | Forzado (PS_SSL_ENABLED=1) |
| Mensajes de error detallados | Desactivados en produccion |
| Archivos de configuracion | Fuera 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
| Item | Estado |
|---|---|
| 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.