LABORATORIO DE SEGURIDAD / 001

Refuerzo de seguridad con Cloudflare

De una solicitud real registrada en Cloudflare Analytics a una regla WAF específica, distinguiendo lo que observé de lo que no pude verificar.

Cloudflare FreeRegla personalizada · BlockCaso · 14 de octubre de 2026

Resumen · 14 de octubre de 2026: vi en los registros de Cloudflare una solicitud GET /.git/config a mi sitio, configuré una regla personalizada que bloquea las rutas con /.git/ y una prueba posterior en el navegador mostró una página de bloqueo de Cloudflare. Esta evidencia no demuestra que se hayan expuesto o descargado archivos Git, ni que el sitio haya sido comprometido.

Revisión de configuración / 15 de octubre de 2026

Revisé mi panel de Cloudflare en modo de solo lectura y confirmé los ajustes guardados que se describen a continuación. Son observaciones de configuración, no nuevas pruebas de comportamiento. El caso original y mis capturas siguen más abajo como evidencia.

Arquitectura

GitHub · jcfinfra/jcfinfra-website
main → npm run build → dist → Cloudflare Pages · jcfinfra-website
Visitantes → controles aplicables en el borde → jcfinfra.com / www.jcfinfra.com

Este flujo conceptual no representa el orden exacto de las fases de procesamiento de Cloudflare. En Pages veo despliegues automáticos de producción desde main y vistas previas para todas las demás ramas. Un envío de cambios a cualquiera de estas ramas puede publicar contenido. El hostname independiente pages.dev requiere su propia evaluación de seguridad.

Ajustes guardados y límites de validación
ControlConfiguración observadaLimitación
Universal SSL / HTTPSCertificado activo; Always Use HTTPS habilitadoSin nueva prueba de cadena de certificados ni de redirección HTTP sin seguimiento automático.
TLSMínimo 1.2; TLS 1.3 habilitadoNo se probó la negociación.
HSTSActivado; un mes; includeSubDomains y preload desactivadosEstado guardado confirmado; sin nueva captura de la cabecera de respuesta.
JCF-Block-Sensitive-FilesActiva · BlockPendiente una nueva correlación entre solicitud y evento.
JCF-Block-Git-MetadataDesactivada · BlockSu patrón Git exacto está incluido en la regla combinada activa.
JCF-Rate-Limit-Web100 solicitudes / 10 segundos / IP; bloqueo de 10 segundos; activaSin prueba de ráfaga; el panel muestra capacidad de 1/1 regla.
DDoSRed y SSL/TLS activos; protección HTTP siempre habilitada según el panel; sin ajustes de anulaciónSin prueba de carga ni de resistencia.

Amenazas y decisiones

La regla combinada activa compara rutas convertidas a minúsculas que contengan /.env, /.svn/, /.hg/, /.github/, /.git/, /wp-config.php, /phpinfo.php o /backup.zip. La regla Git original resulta redundante para su patrón exacto. No modifiqué ninguna regla durante esta revisión.

El filtrado por subcadenas complementa la exclusión de secretos del contenido publicado; no cubre todas las codificaciones o variantes de rutas. La expresión de limitación (starts_with(http.request.uri.path, "/")) cuenta por ip.src, con orden de ejecución First. Su alcance amplio incluye páginas y recursos normales. Las IP compartidas pueden sufrir falsos positivos y el abuso distribuido puede eludir un umbral por IP.

Los controles de transporte no protegen frente a cuentas administrativas comprometidas. No audité los accesos a las cuentas ni las protecciones del repositorio. La cobertura HSTS de subdominios y preload permanecen desactivadas.

Evidencia y validación pendiente

La página del caso cargó correctamente y Pages mostraba el commit de producción 4ce667e.

Me queda pendiente comprobar respuestas HTTP/HTTPS sin seguimiento automático de redirecciones, versiones TLS seleccionadas, rutas normales y solicitudes a rutas sensibles correlacionadas con Security Events. Una ráfaga para probar el límite requiere un plan acotado. No simulé un DDoS. Esta es una revisión limitada de configuración, no una prueba de penetración ni evidencia de protección completa.

01 / Investigar la solicitud

Los registros muestreados de Cloudflare mostraron una solicitud GET /.git/config a jcfinfra.com a las 22:38:37 GMT−5 del 14 de octubre de 2026. El panel mostraba la IP de origen 45.138.12.188 y el ASN 218785 — TC DATACENTER LIMITED.

El evento figuraba como Not mitigated (no mitigado). Esto describe el tratamiento de seguridad mostrado para esa solicitud; no prueba que el archivo existiera o que se devolviera su contenido. El registro disponible no muestra el cuerpo ni el código HTTP de la respuesta.

Una captura de navegador anterior a la regla muestra contenido del portafolio en esa misma ruta. Es compatible con una ruta de respaldo, pero no demuestra la configuración de enrutamiento ni la respuesta de la solicitud original. La IP y el ASN son contexto del evento, no atribución a una persona ni prueba de que el operador de red haya realizado la solicitud.

02 / Aplicar un control específico

Regla: JCF-Block-Git-Metadata
Acción: Block

lower(http.request.uri.path) contains "/.git/"

La expresión convierte la ruta a minúsculas y busca la subcadena literal /.git/. El bloqueo se basa en la ruta, no en la IP: las solicitudes de otras direcciones también pueden coincidir.

Solicitud del cliente → regla personalizada de Cloudflare → ruta coincidente: Block
Ruta no coincidente → continúa por las demás reglas y el enrutamiento aplicables

La captura del editor muestra esta expresión con Block y Active seleccionados. Una captura posterior muestra la regla guardada. Cloudflare documenta la disponibilidad de reglas personalizadas y la acción Block en Free; esta implementación no requiere una función de pago. Documentación de reglas personalizadas de Cloudflare.

03 / Validar sin exagerar los resultados

Estado de la evidencia y verificación histórica
ComprobaciónResultadoLímite de la evidencia
Solicitud originalNot mitigatedVisible en el registro ampliado; sin código ni cuerpo de respuesta.
Regla personalizada guardadaBlockSe revisaron las capturas del editor y del listado posterior.
Prueba posterior en navegadorPágina de bloqueo de CloudflareVisible en la captura; atribuirla a una regla concreta requiere correlacionar un Security Event.
Pruebas HTTP y HTTPSProbé ambas y obtuve el bloqueo en las dosLa captura no muestra el esquema. HSTS o una redirección pueden convertir HTTP en HTTPS; no se establecieron resultados independientes de cada protocolo.
Portada y HSTSHTTP 200; HSTS max-age=2592000Comprobación HTTPS HEAD del 14 de octubre de 2026 a las 23:30 GMT−5. La cabecera no incluía includeSubDomains ni preload.

Yo ya tenía HSTS activado. Este mecanismo obliga a usar HTTPS en clientes compatibles; no sustituye la regla de bloqueo por ruta.

Comprobación posterior reproducible

Si repito la prueba, registro hora, estado, cabecera Location y Ray ID de cada solicitud y correlaciono el Ray ID con la regla en Security Events. Mantengo separadas las solicitudes HTTP y HTTPS y desactivo el seguimiento automático de redirecciones. Compruebo también la portada y las páginas normales. No desactivo la regla existente para recrear el evento original.

04 / Galería de evidencias

Capturas originales mías. Las copias de publicación están recortadas para excluir detalles de cuenta, interfaz del navegador y tráfico ajeno al caso. Los pies indican qué demuestra cada imagen; no se usan reconstrucciones del panel. Se conserva el idioma original de las capturas.

Detalle de solicitud de Cloudflare: Not mitigated, GET /.git/config y ASN de origen.
E01 · Detalle de la solicitud original. Recorte que conserva el evento pertinente y sus detalles ampliados.
Abrir evidencia original ↗
Editor de JCF-Block-Git-Metadata con expresión de ruta en minúsculas, Block y Active.
E02 · Editor antes del despliegue: demuestra intención de configuración, no basta para probar el despliegue.
Abrir evidencia original ↗
Listado de la regla personalizada guardada con acción Block.
E03 · Listado posterior de la regla guardada. El contador de eventos no se usa como indicador de éxito.
Abrir evidencia original ↗
Página de Cloudflare que indica que el acceso a jcfinfra.com está bloqueado.
E04 · Página de bloqueo posterior. Se excluyen la interfaz del navegador y el pie con Ray ID. No se ven el esquema, código HTTP ni la regla exacta responsable.
Abrir evidencia original ↗

05 / Alcance y lecciones aprendidas

  • El control cubre un patrón concreto; no constituye una evaluación completa del WAF ni demuestra que el sitio sea seguro.
  • La expresión exacta no coincide con /.git sin la barra final. No se probaron rutas codificadas, normalización, hostnames alternativos ni acceso directo al origen.
  • Los metadatos del repositorio deben quedar fuera de los archivos publicados. El filtrado en el borde es un control adicional.
  • Los registros muestreados no representan todo el tráfico. La geografía de la solicitud y la del registro del ASN pueden diferir; ninguna establece la ubicación de un atacante.
  • Alojamiento: Cloudflare Pages, según mi panel de Cloudflare para jcfinfra-website.pages.dev, jcfinfra.com y www.jcfinfra.com. No se debe asumir que una regla de zona protege el hostname pages.dev independiente.

Lección práctica: identificar un patrón concreto, aplicar un control proporcionado, validar el comportamiento observable y conservar los límites de la evidencia en el informe.

← Volver a proyectos