Guía de Seguridad
Medidas de Seguridad Implementadas
1. Protección de Archivos
El plugin incluye múltiples capas de protección:
Archivos index.php
Todas las carpetas contienen un archivo index.php vacío que previene el listado de directorios.
Archivo .htaccess
Bloquea el acceso a:
- Archivos de documentación (.md)
- Archivos de configuración (composer.json, package.json)
- Archivos de logs
- Instalador (install.php) después de la instalación
2. Validación de Datos
TODAS las entradas de usuario se validan con SR_Validator:
// Ejemplo de validación
if ( ! SR_Validator::is_valid_email( $email ) ) {
return new WP_Error( 'invalid_email', 'Email no válido' );
}
if ( ! SR_Validator::is_required( $name ) ) {
return new WP_Error( 'missing_name', 'El nombre es obligatorio' );
}
Métodos disponibles:
is_required()- Campo obligatoriois_valid_email()- Email válidois_valid_phone()- Teléfono válidois_valid_url()- URL válidais_valid_nif()- NIF/CIF españolis_numeric()- Número válidois_positive()- Número positivois_in_range()- Dentro de rango- Y más...
3. Sanitización de Datos
TODAS las entradas se limpian con SR_Sanitizer antes de guardar en BD:
// Ejemplo de sanitización
$clean_data = array(
'name' => SR_Sanitizer::sanitize_text( $input['name'] ),
'email' => SR_Sanitizer::sanitize_email( $input['email'] ),
'phone' => SR_Sanitizer::sanitize_phone( $input['phone'] ),
'price' => SR_Sanitizer::sanitize_price( $input['price'] ),
);
Métodos disponibles:
sanitize_text()- Texto planosanitize_email()- Emailsanitize_phone()- Teléfonosanitize_price()- Precio/decimalsanitize_url()- URLsanitize_json()- JSONsanitize_date()- Fecha- Y más...
4. Escape de Salida
TODAS las salidas HTML usan funciones de escape de WordPress:
// En las vistas
echo esc_html( $order->order_number );
echo esc_attr( $customer->name );
echo esc_url( $shop->website );
echo esc_textarea( $order->notes );
NUNCA hagas:
// ❌ INCORRECTO - Vulnerable a XSS
echo $user_input;
echo "<div>$variable</div>";
// ✅ CORRECTO
echo esc_html( $user_input );
echo '<div>' . esc_html( $variable ) . '</div>';
5. Nonces (CSRF Protection)
TODOS los formularios usan nonces:
// En el formulario
wp_nonce_field( 'sr_create_order', 'sr_order_nonce' );
// Al procesar
if ( ! isset( $_POST['sr_order_nonce'] ) ||
! wp_verify_nonce( $_POST['sr_order_nonce'], 'sr_create_order' ) ) {
wp_die( 'Error de seguridad' );
}
6. Verificación de Capabilities
TODAS las operaciones verifican permisos:
// Verificar permiso antes de la acción
if ( ! current_user_can( 'sr_edit_orders' ) ) {
wp_die( __( 'No tienes permiso para editar órdenes.', 'sistema-reparaciones' ) );
}
7. SQL Injection Prevention
TODAS las queries usan $wpdb->prepare():
// ✅ CORRECTO - Protegido
$order = $wpdb->get_row( $wpdb->prepare(
"SELECT * FROM {$table} WHERE id = %d",
$order_id
) );
// ❌ INCORRECTO - Vulnerable
$order = $wpdb->get_row( "SELECT * FROM {$table} WHERE id = {$order_id}" );
8. Protección de Acceso Directo
Todos los archivos PHP verifican contexto de WordPress:
// Al inicio de cada archivo PHP
if ( ! defined( 'ABSPATH' ) ) {
exit; // Salir si se accede directamente
}
9. Roles y Capabilities Granulares
El sistema usa capabilities específicas en lugar de roles genéricos:
// Capabilities específicas
'sr_view_orders'
'sr_create_orders'
'sr_edit_orders'
'sr_delete_orders'
'sr_view_customers'
'sr_create_customers'
// ... y más
Esto permite control fino de permisos.
10. Logs de Actividad
Los cambios importantes se registran en tablas de historial:
wp_sr_status_history- Cambios de estado de órdeneswp_sr_stock_movements- Movimientos de inventariowp_sr_notifications- Emails enviados
Checklist de Seguridad para Desarrollo
Si extiendes el plugin, SIEMPRE:
Al Recibir Datos del Usuario
- Verificar nonce con
wp_verify_nonce() - Verificar capability con
current_user_can() - Validar datos con
SR_Validator - Sanitizar datos con
SR_Sanitizer
Al Guardar en Base de Datos
- Usar
$wpdb->prepare()para queries - Usar
$wpdb->insert()o$wpdb->update()cuando sea posible - Nunca concatenar directamente variables en SQL
Al Mostrar Datos
- Usar
esc_html()para texto - Usar
esc_attr()para atributos HTML - Usar
esc_url()para URLs - Usar
esc_js()para JavaScript - Usar
esc_textarea()para textareas
En Formularios
- Incluir
wp_nonce_field() - Verificar nonce al procesar
- Usar POST en lugar de GET para operaciones de escritura
- No confiar en datos de
$_REQUEST
En AJAX
- Registrar action con
wp_ajax_ywp_ajax_nopriv_ - Verificar nonce en cada request
- Verificar capability
- Sanitizar entrada
- Escapar salida en JSON
Mejores Prácticas
1. Principio de Mínimo Privilegio
Asigna solo los permisos necesarios:
// ✅ Bueno - Capability específica
if ( current_user_can( 'sr_edit_orders' ) ) {
// Permitir edición
}
// ❌ Malo - Demasiado permisivo
if ( current_user_can( 'manage_options' ) ) {
// Solo para administradores
}
2. Validar en el Servidor
SIEMPRE valida en el servidor, aunque tengas validación en JavaScript:
// La validación JavaScript es solo UX
// La validación PHP es SEGURIDAD
if ( ! SR_Validator::is_valid_email( $email ) ) {
return new WP_Error( 'invalid_email', 'Email inválido' );
}
3. No Confiar en el Cliente
Nunca confíes en datos que vienen del cliente:
// ❌ Malo - Confiar en el cliente
$is_admin = $_POST['is_admin']; // El cliente puede mentir
// ✅ Bueno - Verificar en el servidor
$is_admin = current_user_can( 'manage_options' );
4. Logs de Seguridad
Registra eventos importantes:
// Log de inicio de sesión fallido
if ( ! $login_success ) {
error_log( 'Login fallido para usuario: ' . $username );
}
// Log de cambios críticos
do_action( 'sr_order_status_changed', $order_id, $old_status, $new_status );
5. Rate Limiting
Para operaciones sensibles, implementa límites:
// Ejemplo de rate limiting en AJAX
$transient_key = 'sr_ajax_limit_' . $user_id;
$count = get_transient( $transient_key );
if ( $count && $count > 10 ) {
wp_send_json_error( 'Demasiadas peticiones' );
}
set_transient( $transient_key, ( $count + 1 ), MINUTE_IN_SECONDS );
Vulnerabilidades Comunes a Evitar
1. SQL Injection
// ❌ VULNERABLE
$query = "SELECT * FROM table WHERE id = {$_GET['id']}";
// ✅ SEGURO
$query = $wpdb->prepare( "SELECT * FROM table WHERE id = %d", $_GET['id'] );
2. XSS (Cross-Site Scripting)
// ❌ VULNERABLE
echo "<h1>Bienvenido " . $_GET['name'] . "</h1>";
// ✅ SEGURO
echo '<h1>Bienvenido ' . esc_html( $_GET['name'] ) . '</h1>';
3. CSRF (Cross-Site Request Forgery)
// ❌ VULNERABLE - Sin nonce
if ( $_POST['delete'] ) {
delete_order( $_POST['id'] );
}
// ✅ SEGURO - Con nonce
if ( wp_verify_nonce( $_POST['nonce'], 'delete_order' ) ) {
delete_order( $_POST['id'] );
}
4. Directory Traversal
// ❌ VULNERABLE
$file = $_GET['file'];
include( "templates/{$file}.php" );
// ✅ SEGURO
$file = basename( $_GET['file'] ); // Elimina ../ y rutas
$allowed_files = array( 'template1', 'template2' );
if ( in_array( $file, $allowed_files ) ) {
include( "templates/{$file}.php" );
}
5. Remote Code Execution
// ❌ VULNERABLE - NUNCA uses eval()
eval( $_POST['code'] );
// ❌ VULNERABLE - NUNCA uses unserialize() con datos del usuario
$data = unserialize( $_POST['data'] );
// ✅ SEGURO - Usa json_decode()
$data = json_decode( $_POST['data'], true );
Checklist de Auditoría de Seguridad
Antes de lanzar a producción:
- Todos los formularios tienen nonces
- Todas las queries usan
$wpdb->prepare() - Todos los outputs usan funciones de escape
- Todas las operaciones verifican capabilities
- Todas las entradas se validan y sanitizan
- No hay
eval()niunserialize()de datos del usuario - Los archivos .md y .log están bloqueados
- El instalador (install.php) está eliminado o bloqueado
- Los directorios tienen archivos index.php
- WP_DEBUG está deshabilitado en producción
- Las credenciales no están en el código
- Los errores no revelan información sensible
Mantenimiento de Seguridad
Actualizaciones Regulares
- WordPress: Mantener actualizado
- PHP: Usar versiones soportadas
- MySQL: Usar versiones recientes
- Plugin: Aplicar parches de seguridad
Backups
- Backup diario de la base de datos
- Backup semanal de archivos
- Probar restauración periódicamente
Monitoreo
- Revisar logs de error regularmente
- Monitorear intentos de login fallidos
- Vigilar cambios inesperados en archivos
Reporte de Vulnerabilidades
Si encuentras una vulnerabilidad de seguridad:
- NO la publiques públicamente
- Envía un reporte privado a: [correo de seguridad]
- Incluye:
- Descripción de la vulnerabilidad
- Pasos para reproducirla
- Impacto potencial
- Solución sugerida (si la tienes)
Certificación de Seguridad
El plugin Sistema de Gestión de Reparaciones implementa las mejores prácticas de seguridad de WordPress y ha sido revisado siguiendo las guías de OWASP y WordPress Security Team.
Fecha de última revisión: 2026-02-10