Seguridad en Aplicaciones Web: Guía OWASP Top 10 para Laravel

26 Oct 2025
Seguridad
418 lecturas

Protegé tu aplicación Laravel de las 10 vulnerabilidades más críticas según OWASP. Guía práctica con ejemplos de código y soluciones.

Seguridad en Aplicaciones Web: Guía OWASP Top 10 para Laravel

OWASP Top 10: Las Amenazas Más Críticas

El OWASP Top 10 es el estándar de facto para seguridad de aplicaciones web. Esta lista identifica las 10 vulnerabilidades más críticas que todo desarrollador debe conocer y prevenir.

En esta guía analizamos cada vulnerabilidad y cómo proteger tu aplicación Laravel contra ellas.

¿Qué es OWASP?

OWASP (Open Web Application Security Project) es una fundación sin fines de lucro dedicada a mejorar la seguridad del software. Su Top 10 se actualiza cada 3-4 años basándose en datos reales de vulnerabilidades.

Por Qué Importa

  • 43% de las brechas de datos afectan a pequeñas empresas
  • El costo promedio de un data breach es $4.24 millones USD
  • 95% de las vulnerabilidades web caen en el OWASP Top 10
  • Cumplimiento normativo (GDPR, PDPA Argentina) lo requiere

OWASP Top 10 (2021) Explicado

1. Broken Access Control

Qué es: Usuarios accediendo a recursos que no deberían (ej: datos de otros usuarios)

Ejemplo de Vulnerabilidad

// ❌ VULNERABLE: No valida si el usuario tiene permiso
Route::get('/invoice/{id}', function($id) {
    $invoice = Invoice::find($id);
    return view('invoice', compact('invoice'));
});

Ataque: Usuario modifica URL de /invoice/123 a /invoice/124 y ve factura de otro cliente.

Solución en Laravel

// ✅ SEGURO: Valida ownership
Route::get('/invoice/{id}', function($id) {
    $invoice = Invoice::where('id', $id)
        ->where('user_id', auth()->id())
        ->firstOrFail();
    return view('invoice', compact('invoice'));
});

// O mejor aún, usa Policies
Route::get('/invoice/{invoice}', function(Invoice $invoice) {
    $this->authorize('view', $invoice);
    return view('invoice', compact('invoice'));
});

// InvoicePolicy.php
public function view(User $user, Invoice $invoice)
{
    return $user->id === $invoice->user_id;
}

2. Cryptographic Failures

Qué es: Datos sensibles expuestos por falta o mala implementación de encriptación

Ejemplo de Vulnerabilidad

// ❌ VULNERABLE: Almacenar tarjeta de crédito en texto plano
DB::table('payments')->insert([
    'user_id' => $user->id,
    'credit_card' => $request->credit_card, // ¡Nunca hagas esto!
]);

Solución en Laravel

// ✅ SEGURO: Usar encriptación de Laravel
use Illuminate\Support\Facades\Crypt;

// Almacenar
DB::table('sensitive_data')->insert([
    'user_id' => $user->id,
    'data' => Crypt::encryptString($sensitiveData),
]);

// Recuperar
$decrypted = Crypt::decryptString($encrypted);

// Para datos que deben ser buscables, usar hashing
$hashed = Hash::make($password);
Hash::check($plainText, $hashed); // Verificar

Mejores prácticas:

  • Nunca almacenar tarjetas de crédito (usar Stripe, MercadoPago)
  • Usar HTTPS en producción (certificado SSL)
  • Encriptar datos sensibles en DB
  • Hash de passwords con Bcrypt (Laravel lo hace por defecto)

3. Injection (SQL Injection, XSS, etc.)

Qué es: Insertar código malicioso en queries, comandos o scripts

SQL Injection

// ❌ VULNERABLE: Concatenación directa
$email = $request->email;
$user = DB::select("SELECT * FROM users WHERE email = '$email'");

// Ataque: $email = "' OR 1=1 --"
// Query resultante: SELECT * FROM users WHERE email = '' OR 1=1 --'
// Devuelve TODOS los usuarios
// ✅ SEGURO: Usar Eloquent o Query Builder
$user = User::where('email', $request->email)->first();

// O con bindings
$users = DB::select('SELECT * FROM users WHERE email = ?', [$request->email]);

XSS (Cross-Site Scripting)

// ❌ VULNERABLE: Imprimir input sin escapar
<div>{{ $user->bio }}</div> // Si bio tiene <script>, se ejecuta

// ✅ SEGURO: Blade escapa por defecto
{{ $user->bio }} // Escapado automáticamente

// Para HTML confiable, usa {!! !!} con extremo cuidado
{!! Purifier::clean($user->bio) !!} // Usa HTMLPurifier

4. Insecure Design

Qué es: Fallas de diseño arquitectural, no bugs de implementación

Ejemplos

  • No rate limiting: API permite 1000 requests/segundo = DoS fácil
  • Recuperación de password insegura: "¿Cuál es el nombre de tu mascota?"
  • No CAPTCHA en registro: Bots crean miles de cuentas

Solución en Laravel

// Rate Limiting
Route::middleware('throttle:60,1')->group(function () {
    Route::post('/api/endpoint', [Controller::class, 'method']);
});

// CAPTCHA (Google reCAPTCHA v3)
// En ContactController (ya implementado en el proyecto)
$recaptchaToken = $request->input('recaptcha_token');
$response = Http::asForm()->post('https://www.google.com/recaptcha/api/siteverify', [
    'secret' => config('services.recaptcha.secret'),
    'response' => $recaptchaToken,
]);

if (!$response->json()['success'] || $response->json()['score'] < 0.5) {
    return back()->withErrors(['message' => 'Verificación de seguridad falló']);
}

5. Security Misconfiguration

Qué es: Configuraciones inseguras o por defecto

Errores Comunes

Error Riesgo Solución
Debug mode en producción Expone rutas de archivos, DB APP_DEBUG=false en .env
Listado de directorios habilitado Ver archivos del servidor Options -Indexes en .htaccess
Headers de seguridad faltantes XSS, clickjacking Middleware de headers
Versiones antiguas de PHP/Laravel Vulnerabilidades conocidas Actualizar regularmente

Headers de Seguridad (Middleware)

// app/Http/Middleware/SecurityHeaders.php
public function handle($request, Closure $next)
{
    $response = $next($request);

    $response->headers->set('X-Frame-Options', 'DENY');
    $response->headers->set('X-Content-Type-Options', 'nosniff');
    $response->headers->set('X-XSS-Protection', '1; mode=block');
    $response->headers->set('Referrer-Policy', 'strict-origin-when-cross-origin');
    $response->headers->set('Content-Security-Policy', "default-src 'self'");

    return $response;
}

6. Vulnerable and Outdated Components

Qué es: Usar librerías con vulnerabilidades conocidas

Prevención

# Auditar dependencias regularmente
composer audit

# Actualizar dependencias
composer update

# En package.json
npm audit
npm audit fix

Monitoreo automático:

  • GitHub Dependabot (alertas automáticas)
  • Snyk.io (escaneo de vulnerabilidades)
  • Renovate Bot (PRs automáticos para updates)

7. Identification and Authentication Failures

Qué es: Fallas en autenticación y gestión de sesiones

Ejemplo: Brute Force Attack

// ✅ Laravel incluye rate limiting en login
// En LoginController
use Illuminate\Foundation\Auth\ThrottlesLogins;

protected $maxAttempts = 5; // 5 intentos
protected $decayMinutes = 15; // Bloqueo de 15 minutos

2FA (Two-Factor Authentication)

// Instalar Laravel Fortify
composer require laravel/fortify

// Habilitar 2FA
// config/fortify.php
'features' => [
    Features::twoFactorAuthentication([
        'confirm' => true,
        'confirmPassword' => true,
    ]),
],

8. Software and Data Integrity Failures

Qué es: Código o infraestructura que confía en fuentes no verificadas

Ejemplo: Dependency Confusion

// ❌ VULNERABLE: Instalar paquetes sin verificar
composer require paquete-random

// ✅ SEGURO: Verificar source y reputación
// - Revisar downloads en Packagist
// - Ver actividad en GitHub
// - Leer código antes de usar
// - Usar lock files (composer.lock, package-lock.json)

9. Security Logging and Monitoring Failures

Qué es: No detectar, alertar o responder a brechas

Logging Correcto

// Loguear eventos de seguridad
Log::warning('Failed login attempt', [
    'email' => $request->email,
    'ip' => $request->ip(),
    'user_agent' => $request->userAgent(),
]);

Log::critical('Unauthorized access attempt', [
    'user_id' => auth()->id(),
    'resource' => $request->url(),
]);

Herramientas de monitoreo:

  • Laravel Telescope (desarrollo)
  • Sentry.io (errores en producción)
  • LogRocket (session replay)
  • Fail2Ban (bloqueo automático de IPs)

10. Server-Side Request Forgery (SSRF)

Qué es: Engañar al servidor para que haga requests no autorizados

Ejemplo de Vulnerabilidad

// ❌ VULNERABLE: Fetch URL del usuario sin validar
$url = $request->input('url');
$content = file_get_contents($url);

// Ataque: $url = "file:///etc/passwd" o "http://localhost/admin"

Solución

// ✅ SEGURO: Validar y sanitizar URLs
$url = $request->input('url');

// Validar esquema
if (!str_starts_with($url, 'https://')) {
    abort(400, 'Only HTTPS allowed');
}

// Whitelist de dominios
$allowedDomains = ['api.example.com', 'cdn.example.com'];
$domain = parse_url($url, PHP_URL_HOST);

if (!in_array($domain, $allowedDomains)) {
    abort(403, 'Domain not allowed');
}

// Usar HTTP client de Laravel con timeout
$response = Http::timeout(5)->get($url);

Checklist de Seguridad para Laravel

Configuración (.env)

  • APP_DEBUG=false en producción
  • APP_KEY generado y secreto
  • APP_URL con HTTPS
  • ☐ Credenciales DB no por defecto

Código

  • ☐ Usar Eloquent/Query Builder (no raw SQL)
  • ☐ Validar TODOS los inputs ($request->validate())
  • ☐ Sanitizar outputs ({{ }} en Blade)
  • ☐ CSRF protection habilitado (@csrf en forms)
  • ☐ Policies para authorization
  • ☐ Rate limiting en APIs y forms

Infraestructura

  • ☐ SSL/TLS certificado válido
  • ☐ Firewall configurado
  • ☐ SSH con keys (no passwords)
  • ☐ Backups automáticos
  • ☐ PHP y dependencias actualizadas

Herramientas de Testing de Seguridad

Herramienta Qué Detecta Costo
OWASP ZAP Vulnerabilidades web automáticas Gratis
Burp Suite Penetration testing completo Gratis / $399/año Pro
Snyk Vulnerabilidades en dependencias Gratis / Planes pagos
SonarQube Code quality + seguridad Gratis / Enterprise

Conclusión

La seguridad no es opcional. Una brecha puede:

  • 💸 Costar millones en multas y remediación
  • 😰 Destruir la confianza de tus clientes
  • ⚖️ Resultar en consecuencias legales
  • 📉 Arruinar la reputación de tu marca

La buena noticia: Laravel incluye protecciones por defecto contra la mayoría del OWASP Top 10. Pero debes usarlas correctamente.

En SofihaCloud desarrollamos aplicaciones con security-first approach:

  • 🔒 Auditorías de seguridad incluidas
  • ✅ Cumplimiento OWASP Top 10
  • 🛡️ Penetration testing antes de producción
  • 📊 Monitoreo y logging robustos
  • 🔄 Actualizaciones de seguridad proactivas

¿Tu aplicación está protegida?

📞 Contactanos para una auditoría de seguridad gratuita.

¿Te gustó este artículo?

Descubrí cómo podemos ayudarte a implementar estas soluciones en tu empresa.

Consultá Gratis
¿Necesitas ayuda? ¡Escríbenos!