Ficheros php.ini y httpd.conf completamente securizados, explicando parámetro a parámetro las modificaciones aplicadas para ocultar información del servidor, deshabilitar funciones peligrosas, limitar recursos y restringir accesos no deseados. Para convertir un XAMPP (servidor web Apache) de desarrollo en un servidor listo para entornos de producción, pendiente únicamente de la migración a HTTPS. Mostramos algunos ejemplos de ataques, intentos de intrusión o de detectar vulnerabilidades en servidor web y cómo saber si han sido bloqueados.

¿Por qué es necesario endurecer la configuración de XAMPP (servidor web Apache)?

XAMPP es una herramienta excelente para el desarrollo local, pero su configuración por defecto está orientada a la facilidad de uso, y al desarrollo, no a la seguridad. Directivas como display_errors=OnOptions Indexes o la exposición de la versión de PHP y Apache son útiles durante el desarrollo, pero representan vulnerabilidades críticas en un entorno de producción.

Cuando desplegamos una API REST en un servidor accesible desde Internet, estamos exponiendo nuestro código a todo tipo de sondeos automáticos: bots que buscan archivos sensibles como .env.git/config, rutas de administración no protegidas o intentos de ejecución remota de comandos. Sin una configuración adecuada, el servidor puede filtrar información valiosa para un atacante (versiones exactas de software, rutas absolutas del sistema de archivos, estructura de directorios) o incluso permitir la ejecución de código malicioso.

Hay que tener en cuenta que los entornos XAMPP no son los ideales para despliegues de producción. Aún así, si tenemos que exponerlos a Internet, será muy recomendable aplicar las buenas prácticas que indicaremos en este tutorial.

Cada parámetro que modifiquemos para endurecer la seguridad irá acompañado de su justificación técnica, el riesgo que mitiga y el posible impacto en la funcionalidad de la aplicación.

Consideración importante: Antes de aplicar cualquier cambio en un entorno de producción, es imprescindible:

  1. Realizar una copia de seguridad de los archivos de configuración originales (php.inihttpd.conf) y del código fuente de la aplicación.
  2. Probar cada cambio de forma individual en un entorno de pruebas idéntico al de producción. Probando cada parámetro o grupo de parámetros modificado de forma progresiva, no incluyéndolos todos «de golpe» porque puede que el servidor web no se inicie y no sepamos cuál está provocando el error.
  3. Verificar el funcionamiento completo de la API después de cada modificación, incluyendo autenticación, subida de archivos, consumo de servicios externos y cualquier otra funcionalidad crítica.
  4. Monitorizar los logs durante el proceso para detectar errores inesperados o falsos positivos en los bloqueos.

php.ini para PHP y httpd.conf para Apache

A continuación, presentamos dos archivos de configuración completos que representan el estado final de nuestro proceso de hardening:

  1. php.ini – Configuración del intérprete PHP con directivas de seguridad activas.
  2. httpd.conf – Configuración del servidor Apache con restricciones de acceso y ocultación de información.

Ambos archivos se muestran sin comentarios para facilitar su lectura y comprensión directa de las directivas activas.

Limitaciones de esta configuración

El proceso que mostramos aquí es un punto de partida sólido, pero no exhaustivo. Quedan fuera del alcance de este artículo aspectos como:

  • Configuración de HTTPS con certificados válidos (aunque mencionaremos los pasos necesarios).
  • Implementación de un WAF (Web Application Firewall).
  • Sistemas de detección de intrusiones.
  • Monitorización avanzada de logs y alertado en tiempo real.
  • Configuración para entornos específicos.

El siguiente paso lógico después de aplicar estas configuraciones sería migrar la comunicación a HTTPS, ya que muchas de las directivas de seguridad relacionadas con cookies (session.cookie_secure) o la integridad de los datos requieren una conexión cifrada para ser realmente efectivas.

Ejemplo de php.ini securizado y parámetros añadidos

php.ini

La descarga del fichero php.ini securizado de ejemplo:

El contenido del fichero php.ini securizado:

Parámetros modificados/añadidos en php.ini y su finalidad técnica

ParámetroValor originalNuevo valorFinalidad técnica
expose_phpOnOffElimina la cabecera X-Powered-By: PHP/X.X.X en las respuestas HTTP, dificultando la fingerprinting del servidor.
max_execution_time12030Limita el tiempo máximo de ejecución de cada script. Mitiga ataques de denegación de servicio (DoS) mediante bucles infinitos o procesos largos.
max_input_time6020Restringe el tiempo de parseo de datos entrantes (POST, GET, FILES). Previene ataques de slowloris a nivel de aplicación.
max_input_nesting_level(sin límite)64Limita la profundidad de anidamiento en arrays de entrada ($_GET$_POST). Previene ataques de agotamiento de pila mediante JSON/XML profundamente anidados.
max_input_vars(sin límite)1000Limita el número de variables de entrada por petición. Protege contra ataques de hash flooding en arrays asociativos.
memory_limit512M128MRestringe la memoria máxima que un script puede consumir. Mitiga ataques de tipo memory exhaustion (ej: procesamiento de imágenes gigantes).
open_basedir(sin definir)D:\xampp\htdocs;D:\xampp\tmpRestringe el acceso del sistema de archivos a los directorios especificados. Previene Local File Inclusion (LFI) y acceso a archivos sensibles del sistema.
display_errorsOnOffEvita que los errores PHP se muestren al cliente. Previene la fuga de información sensible (rutas, credenciales, estructura de BD).
display_startup_errorsOnOffOculta errores ocurridos durante el inicio de PHP. Previene exposición de configuración interna.
log_errors_max_len10240Establece longitud máxima del log de errores. Valor 0 sin límite para registro completo en entornos forenses.
html_errorsOnOffDeshabilita el formato HTML en mensajes de error. Reduce información útil para atacantes.
ignore_repeated_errorsOffOnNo registra errores repetidos en el mismo archivo y línea. Reduce ruido en logs y evita ataques de relleno.
post_max_size40M10MLimita el tamaño máximo de datos POST. Protege contra ataques de DoS mediante peticiones masivas.
upload_max_filesize40M10MRestringe el tamaño de archivos subidos. Mitiga ataques de subida de archivos maliciosos de gran tamaño.
max_file_uploads205Limita el número de archivos por petición. Previene DoS mediante subida masiva de archivos pequeños.
allow_url_fopenOnOffDeshabilita la apertura de archivos remotos (HTTP/FTP). Previene ataques de Remote File Inclusion (RFI).
allow_url_includeOffOff (mantenido)Previene inclusión remota de archivos. Crítico contra RFI.
default_socket_timeout6030Tiempo de espera para conexiones de socket. Mitiga ataques de slow reading.
disable_functions(vacío)35+ funcionesDeshabilita funciones peligrosas como exec()system()proc_open()phpinfo(). Previene ejecución remota de comandos (RCE) y fuga de información.
session.use_strict_mode01Rechaza IDs de sesión no inicializados. Previene fijación de sesión (session fixation).
session.cookie_httponly(vacío)1Impide acceso a la cookie de sesión desde JavaScript. Mitiga robo de sesión por XSS.
session.cookie_secure(vacío)1Fuerza que la cookie de sesión solo se transmita por HTTPS. Previene captura en redes no seguras.
session.cookie_samesite(vacío)«Strict»Previene envío de cookies en peticiones cross-site. Mitiga CSRF (Cross-Site Request Forgery).
session.gc_maxlifetime14401800Tiempo de vida de sesión en segundos. Reduce ventana de ataque en sesiones inactivas.
session.sid_length2632Aumenta longitud del ID de sesión. Incrementa entropía y dificulta ataques de fuerza bruta.
session.sid_bits_per_character56Aumenta bits por carácter en ID de sesión (0-9, a-z, A-Z, -, ,). Mejora entropía total.
date.timezoneEurope/BerlinUTCEvita dependencia de zona horaria local. Mejora consistencia de logs forenses.
zend.exception_ignore_argsOffOnOculta argumentos en stack traces de excepciones. Previene fuga de parámetros sensibles.
zend.exception_string_param_max_len150Suprime completamente valores de strings en excepciones. Previene exposición de datos sensibles.

Ejemplo de httpd.conf securizado y parámetros añadidos

httpd.conf

La descarga del fichero httpd.conf securizado de ejemplo:

El contenido del fichero httpd.conf securizado (con dos IP públicas bloqueadas, a modo de ejemplo):

Parámetros modificados/añadidos en httpd.conf y su finalidad técnica

Parámetro/DirectivaValor originalNuevo valorFinalidad técnica
OptionsIndexes FollowSymLinks Includes ExecCGI-Indexes +FollowSymLinks -Includes -ExecCGIDesactiva listado de directorios (-Indexes), SSI (-Includes) y ejecución de CGI (-ExecCGI). Previene fuga de información y ejecución remota de scripts.
ServerTokens(no definido)ProdReduce información en cabecera Server. Muestra solo «Apache», sin versión ni SO. Dificulta fingerprinting.
ServerSignature(no definido)OffElimina firma del servidor en páginas de error. Previene fuga de información sobre versión y módulos.
TraceEnable(no definido)OffDeshabilita el método HTTP TRACE. Previene ataques de Cross-Site Tracing (XST).
EnableMMAPOnoffDeshabilita memory-mapping. Previene problemas con archivos en sistemas de red y evita ciertos ataques de timing.
EnableSendfileOff (mantenido)offDeshabilita sendfile syscall. Previene ataques de race condition en sistemas de archivos remotos.
Timeout30060Reduce tiempo máximo de espera por petición. Mitiga ataques Slowloris y DoS.
KeepAliveTimeout55 (mantenido)Tiempo de espera para siguiente petición en misma conexión. Balance entre rendimiento y seguridad.
LimitRequestBody(no definido)10485760 (10MB)Limita tamaño máximo del cuerpo de petición HTTP. Previene DoS por peticiones masivas.
LimitExcept GET POST HEAD(no definido)Require all deniedBloquea métodos HTTP no estándar (PUT, DELETE, OPTIONS, TRACE). Reduce superficie de ataque.
RewriteCond %{REQUEST_URI}(no definido)!^/apirestnu/Restringe acceso solo al directorio de la API. Bloquea sondeos automáticos a rutas sensibles (/.env/.git//.well-known/).
RewriteCond %{HTTP_USER_AGENT}(no definido)Bloqueo de User-Agent maliciososBloquea escáneres automáticos (Keydrop, onlyscans, infrawatch). Reduce ruido en logs y consumo de recursos.
RewriteCond %{REMOTE_ADDR}(no definido)Bloqueo de IPs específicasBloqueo a nivel de firewall virtual de IPs con comportamiento malicioso detectado.
Header always set X-Frame-Options(no definido)SAMEORIGINPreviene clickjacking. Controla que la página solo pueda ser embebida en iframes del mismo origen.
Header always set X-Content-Type-Options(no definido)nosniffPreviene MIME type sniffing. Evita ejecución de scripts camuflados como otros tipos MIME.
Header always set X-XSS-Protection(no definido)1; mode=blockActiva filtro XSS del navegador. Bloquea páginas al detectar ataques cross-site scripting.
Header always set Referrer-Policy(no definido)strict-origin-when-cross-originControla información enviada en cabecera Referer. Previene fugas de URLs sensibles a sitios externos.
ErrorDocument(no definido)" " (espacio vacío)Sustituye páginas de error por respuesta vacía. Previene fuga de información sobre estructura del servidor.
Directory cgi-binRequire all grantedRequire all deniedDeshabilita completamente el directorio CGI. Previene ejecución de scripts CGI maliciosos.
#Include conf/extra/httpd-autoindex.confIncluidoComentadoDesactiva módulo de listado de directorios. Previene exposición de estructura de archivos.
#Include conf/extra/httpd-info.confIncluidoComentadoDesactiva módulo de información del servidor. Previene acceso a /server-status y /server-info.

Ejemplos de intentos de descubrir vulnerabilidades y de ataques a nuestro servidor web

Si abrimos el fichero access.log de Apache, podremos observar si hay intentos de descubrir vulnerabilidades o de ataques a nuestro servidor web, no es la mejor opción, pero de forma rápida se pueden obtener determinados comportamientos de bots y agentes atacantes.

Un ejemplo de contenido de fichero access.log:

Análisis de los logs: Tipos de ataques detectados

EntradaTipo de ataqueObjetivo del atacante
"\x16\x03\x01"TLS/SSL handshake malformadoIntentar negociar conexión HTTPS insegura o explotar vulnerabilidades en OpenSSL
"GET /T6bHkeeG3IixY7Bh0..." (URL larga aleatoria)Fuzzing / Path traversalBuscar buffer overflows o inyección mediante URLs extremadamente largas
"SSH-2.0-Go"Escaneo de serviciosIntentar conexión SSH en puerto 80 (protocolo incorrecto)
"GET /HNAP1/"Escaneo de routers/iotBuscar dispositivos Huawei/D-Link vulnerables (CVE conocidos)
"CONNECT www.shadowserver.org:443"Proxy abuseIntentar usar el servidor como proxy abierto para actividades maliciosas
"GET /geoserver/web/"Escaneo de software específicoBuscar GeoServer vulnerable (CVE-2024-36401, RCE crítico)
"GET /dispatch.asp"Escaneo de aplicaciones ASPBuscar paneles de administración expuestos
"GET /apiui/"Typosquatting / variantesIntentar encontrar endpoints mal escritos de tu API
"GET http://api.ipify.org/..."Server-side request forgery (SSRF)Intentar que el servidor haga peticiones a servicios externos
"GET / HTTP/1.1" (con User-Agent sospechoso)Escaneo de superficieDescubrir qué servicios están expuestos

¿Cómo saber si se están bloqueando estos ataques?

La respuesta está en el código de estado HTTP y el tamaño de la respuesta.

En los logs de access.log:

Interpretación de los códigos de respuesta:

CódigoSignificado¿Bloqueado?
200OK – El recurso existe❌ NO bloqueado (peligro si es un acceso no autorizado)
403Forbidden – Acceso denegado✅ SÍ bloqueado
404Not Found – No existe⚠️ Parcial (revela que no existe)
400Bad Request – Petición malformada✅ SÍ bloqueado (error genérico)
408Request Timeout⚠️ Neutro

Recomendaciones adicionales para fortalecer la seguridad de un servidor web

Para entornos de producción crítica, se recomienda complementar esta configuración con:

  1. WAF (Web Application Firewall) como ModSecurity con reglas OWASP Core Rule Set o sistemas WAF comerciales (Sonicwall, Sophos, CheckPoint, Fortinet, etc.).
  2. Fail2ban para bloqueo automático de IPs maliciosas.
  3. HTTPS obligatorio con certificado válido (Let’s Encrypt o comercial).
  4. Monitorización de logs con herramientas como ELK Stack o SIEM como Splunk, QRadar.
  5. Actualizaciones periódicas del sistema operativo del servidor, de PHP, de Apache y sus módulos.
  6. Principio de mínimo privilegio en usuarios y grupos del sistema.
  7. Aplicar medidas de desarrollo en las API o cualquier servicio web expuesto.