PWR Escudo

Firewall de aplicacion web (WAF) ligero en PHP puro. Detecta y bloquea inyecciones SQL, XSS, path traversal, scanners automatizados y ataques de fuerza bruta. Sin modulos Apache/Nginx, sin dependencias externas.

Instalacion

Escudo es un unico archivo PHP. Copialo a tu proyecto e incluyelo al inicio de tu aplicacion, antes de cualquier otra logica.

PHP
require_once __DIR__ . '/core/escudo.php';

Requisitos minimos

  • PHP 7.4 o superior
  • Sin extensiones adicionales requeridas
  • Permisos de escritura en datos/ y logs/ para rate limiting y logs

Inicio rapido

Con una sola linea activas toda la proteccion WAF. Escudo analiza automaticamente GET, POST, cookies y user-agent en cada peticion.

PHP
require_once 'core/escudo.php';

// Activar WAF con configuracion por defecto
pwr_escudo_iniciar();

// Tu aplicacion continua normalmente
echo 'Aplicacion protegida por PWR Escudo';

Funciones

pwr_escudo_iniciar()

Punto de entrada principal. Analiza la peticion HTTP actual y bloquea si detecta amenazas.

Firma
pwr_escudo_iniciar($config = null): array
ParametroTipoDescripcion
$configarray|nullConfiguracion personalizada. Si es null, carga desde datos/escudo_config.json

Retorna: array con claves bloqueado (bool), razones (array), ip, uri, metodo, timestamp.

Ejemplo
$resultado = pwr_escudo_iniciar();
if ($resultado['bloqueado']) {
    // La peticion fue bloqueada automaticamente
    error_log('Ataque detectado desde ' . $resultado['ip']);
}

pwr_escudo_detectar_sqli()

Analiza una cadena en busca de patrones de inyeccion SQL.

Firma
pwr_escudo_detectar_sqli(string $input): bool
ParametroTipoDescripcion
$inputstringCadena a analizar (valor de GET, POST, cookie, etc.)

Retorna: true si se detecta un patron de SQLi, false en caso contrario.

Ejemplo
$input = $_GET['buscar'] ?? '';
if (pwr_escudo_detectar_sqli($input)) {
    die('Input sospechoso detectado');
}

pwr_escudo_detectar_xss()

Detecta patrones de Cross-Site Scripting en una cadena, incluyendo decodificacion de entidades HTML y URL.

Firma
pwr_escudo_detectar_xss(string $input): bool
ParametroTipoDescripcion
$inputstringCadena a analizar

Retorna: true si se detecta XSS, false en caso contrario.

pwr_escudo_detectar_traversal()

Detecta intentos de path traversal, null bytes y wrappers PHP peligrosos.

Firma
pwr_escudo_detectar_traversal(string $input): bool
ParametroTipoDescripcion
$inputstringCadena a analizar (tipicamente rutas de archivo o URLs)

Retorna: true si se detecta path traversal, false en caso contrario.

pwr_escudo_detectar_scanner()

Identifica user-agents de herramientas de escaneo automatizado (sqlmap, nikto, nmap, etc.).

Firma
pwr_escudo_detectar_scanner(string $user_agent): bool
ParametroTipoDescripcion
$user_agentstringCadena User-Agent de la peticion HTTP

Retorna: true si el user-agent corresponde a un scanner conocido.

pwr_escudo_rate_limit()

Control de tasa de peticiones por IP. Limita el numero de requests en una ventana de tiempo.

Firma
pwr_escudo_rate_limit(string $ip, int $limite = 60, int $ventana = 60): bool
ParametroTipoDescripcion
$ipstringDireccion IP del cliente
$limiteintNumero maximo de peticiones permitidas (defecto: 60)
$ventanaintVentana de tiempo en segundos (defecto: 60)

Retorna: true si la IP ha excedido el limite, false si esta dentro del rango.

pwr_escudo_info()

Devuelve informacion del modulo: version, configuracion activa, estadisticas de eventos y bloqueos del dia.

Firma
pwr_escudo_info(): array

Retorna: array con version, modo, eventos_hoy, bloqueos_hoy, modulos_activos.

Configuracion

La configuracion se almacena en datos/escudo_config.json. Si el archivo no existe, Escudo usa valores por defecto seguros.

datos/escudo_config.json
{
    "modo": "aprendizaje",        // "aprendizaje" (solo log) o "bloqueo" (bloquea activo)
    "log_activado": true,            // Registrar eventos en log
    "log_ruta": "logs/escudo.log",    // Ruta del archivo de log
    "rate_limit": {
        "activado": true,            // Activar control de tasa
        "peticiones": 60,            // Maximo de peticiones por ventana
        "ventana_segundos": 60       // Ventana en segundos
    },
    "sqli": {
        "activado": true,            // Activar deteccion SQLi
        "analizar_get": true,        // Analizar parametros GET
        "analizar_post": true,       // Analizar parametros POST
        "analizar_cookies": true    // Analizar cookies
    },
    "xss": {
        "activado": true,            // Activar deteccion XSS
        "analizar_get": true,
        "analizar_post": true,
        "analizar_cookies": true
    },
    "traversal": {
        "activado": true             // Activar deteccion path traversal
    },
    "whitelist_ips": ["127.0.0.1", "::1"],  // IPs que nunca se bloquean
    "blacklist_ips": [],              // IPs bloqueadas permanentemente
    "rutas_excluidas": [],            // URIs que no se analizan
    "respuesta_bloqueo": {
        "codigo_http": 403,           // Codigo HTTP de respuesta
        "mensaje": "Acceso denegado"  // Mensaje mostrado al atacante
    }
}
Modo aprendizaje: En este modo, Escudo detecta y registra amenazas en el log pero no bloquea las peticiones. Ideal para probar sin afectar a usuarios reales. Cambia a "bloqueo" cuando estes listo para produccion.

Ejemplos

Proteccion basica de toda la aplicacion

Incluye Escudo al principio de tu index.php para proteger todas las peticiones.

index.php
require_once 'core/escudo.php';

// Activar WAF en modo bloqueo
$resultado = pwr_escudo_iniciar([
    'modo' => 'bloqueo',
    'rate_limit' => [
        'activado' => true,
        'peticiones' => 100,
        'ventana_segundos' => 60
    ]
]);

// Si llega aqui, la peticion es segura
echo 'Bienvenido a la aplicacion';

Validacion manual de inputs

Usa las funciones de deteccion individualmente para validar inputs concretos.

PHP
require_once 'core/escudo.php';

$nombre = $_POST['nombre'] ?? '';
$email  = $_POST['email'] ?? '';

// Verificar cada campo individualmente
if (pwr_escudo_detectar_sqli($nombre) || pwr_escudo_detectar_xss($nombre)) {
    die('Campo nombre contiene contenido no permitido');
}

if (pwr_escudo_detectar_sqli($email)) {
    die('Campo email contiene contenido no permitido');
}

Rate limiting personalizado por endpoint

Aplica limites diferentes segun la ruta de la API.

PHP
require_once 'core/escudo.php';

$ip = $_SERVER['REMOTE_ADDR'];
$uri = $_SERVER['REQUEST_URI'];

// Login: maximo 5 intentos por minuto
if (strpos($uri, '/login') !== false) {
    if (pwr_escudo_rate_limit($ip, 5, 60)) {
        http_response_code(429);
        die('Demasiados intentos. Espera un minuto.');
    }
}

// API general: 120 peticiones por minuto
if (pwr_escudo_rate_limit($ip, 120, 60)) {
    http_response_code(429);
    die('Limite de peticiones excedido');
}

Diagnostico del sistema

PHP
require_once 'core/escudo.php';

$info = pwr_escudo_info();
echo 'Escudo v' . $info['version'];
echo 'Modo: ' . $info['modo'];
echo 'Eventos hoy: ' . $info['eventos_hoy'];
echo 'Bloqueos hoy: ' . $info['bloqueos_hoy'];

Log shrink inteligente

Escudo incluye un sistema de rotacion de logs que se activa automaticamente cuando el archivo supera el tamano maximo configurado (log_max_bytes, por defecto 5 MB). En lugar de borrar todo el log o rotar ciegamente, prioriza que eventos conservar:

PrioridadTipo de eventoSe elimina
0 (menor)Aprendizaje, no bloqueado (informativo)Primero
1Rate limit excedidoSegundo
2Scanner/bot detectadoTercero
3 (mayor)Ataques bloqueados (SQLi, XSS, traversal)Ultimo

El shrink reduce el log al 60% del maximo para evitar rotaciones constantes en cada escritura.

Configuracion

JSON — datos/escudo_config.json
{
    "log_max_bytes": 5242880,    // 5 MB (defecto). 0 = sin limite
    "log_activado": true,
    "log_ruta": "logs/escudo.log"
}

Uso manual

PHP
require_once 'core/escudo.php';

// Forzar shrink manual (ej: en cron de mantenimiento)
pwr_escudo_log_shrink('logs/escudo.log', 5 * 1024 * 1024);