Key Technology

Encuentra los endpoints del servidor que tu escáner no puede alcanzar

Los crawlers dinámicos solo encuentran los endpoints que pueden activar desde la interfaz. El código muerto y los bundles protegidos por autenticación esconden endpoints reales del servidor en el JavaScript del cliente — el análisis estático de SolidPoint los encuentra.

The Problem

Lo que el rastreo dinámico pasa por alto

Los crawlers dinámicos descubren endpoints simulando la interacción del usuario: clics, envíos de formularios, navegación. Tres categorías de endpoints del servidor suelen escapar a este enfoque:

1

Código muerto — funciones que existen en el bundle de JavaScript pero nunca se invocan desde la interfaz. Ninguna interacción puede activarlas.

2

Módulos sin instanciar — clases de clientes de API y helpers de solicitudes que se incluyen en el bundle pero no se utilizan en la página actual.

3

Bundles protegidos por autenticación — JavaScript para paneles de administración, funciones autenticadas e interfaces de depuración que se envían a todos los usuarios, incluidos los anónimos. La interfaz oculta estas funciones, pero el código — y los endpoints del servidor que referencia — está a la vista.

Ejemplo: Código muerto con un endpoint activo en el servidor
1  const api = "/application/iuT6ei/";
2  const remove = async (params) => {
3    if (prompt("Enter 'yes' to remove") !== "yes") return;
4    await fetch(api + "interface/remove/handle", {
5      method: "POST", body: JSON.stringify(params)
6    });
7  };
8  const removeByID = (id) => remove({ ident: id });

Estas funciones nunca se llaman en ningún lugar de la página. Ningún botón las activa. Ningún enlace las referencia. Un crawler dinámico que simule clics de usuario nunca ejecutará este código. Pero la llamada a fetch en la línea 4 referencia un endpoint activo del servidor que un escáner debería probar. En nuestra investigación encontramos este patrón exacto en un plugin de WordPress con más de 70.000 instalaciones activas.

Ejemplo: Clase cliente de API sin instanciar
1  class ApiClient {
2    baseURL = '/api/v2/';
3
4    async sendData(payload) {
5      await fetch(this.baseURL + 'data/ingest', {
6        method: 'POST', body: JSON.stringify(payload)
7      });
8    }
9  }

Si esta clase no se instancia en la página, la llamada a fetch de la línea 5 es invisible para los crawlers. La coincidencia de URLs por regex tampoco la encontrará — la URL está dividida entre un campo de clase y un método, y requiere resolver this.baseURL. Los escáneres de la industria probados en nuestra investigación — incluidos Acunetix, Burp Scanner, HCL AppScan, Detectify y PT BlackBox Scanner — no encontraron ningún endpoint oculto en código como este.

Estos no son casos excepcionales. En nuestras pruebas sobre cinco aplicaciones de referencia, encontramos bundles de JavaScript del lado del cliente que contenían endpoints para paneles de administración, funciones autenticadas, funciones deshabilitadas e interfaces de depuración. El código del lado del servidor detrás de estos endpoints estaba activo y era potencialmente explotable.

Our Approach

Cómo funciona el análisis estático de SolidPoint

Todos los escáneres rastrean HTML y simulan clics. SolidPoint añade una tercera capa:

1

Rastreo estático

Enlaces HTML, formularios y marcado estándar. La base que hace cualquier escáner.

2

Rastreo dinámico

Interacción con navegador headless — simulando clics, envíos de formularios y navegación.

3

Análisis estático de JavaScript

Análisis a nivel de AST de todo el JavaScript de la página, incluyendo código muerto y bundles protegidos por autenticación. Este es el diferenciador de SolidPoint.

Deep Dive

Dentro del motor de análisis estático

Análisis multi-pasada

Cuatro pasadas sobre el AST de JavaScript acumulan conocimiento sobre los valores de las variables, los argumentos de las funciones y los valores de retorno, construyendo una imagen progresivamente más completa del flujo de datos del programa.

Recorrido de cadenas de llamadas

Rastrea el flujo de datos a través de hasta 5 niveles de llamadas a funciones anidadas — resolviendo argumentos, valores de retorno y variables globales compartidas entre invocadores.

Análisis de código muerto

Visita todos los nodos del AST sin importar si son alcanzables — incluyendo funciones nunca invocadas y ramas muertas. Código que el análisis dinámico omite por completo.

Descubrimiento tras autenticación

Los bundles de JS del cliente suelen enviar código para paneles de administración y funciones autenticadas a todos los usuarios. El analizador encuentra esos endpoints sin credenciales.

OOP y resolución de clases

Resuelve this en clases ES6 y en patrones basados en prototipos. Rastrea baseURL desde la asignación en el constructor hasta su uso en métodos.

Reconocimiento de sinks AJAX

Identifica patrones de envío de solicitudes en fetch, $.ajax/$.post de jQuery, axios, $http de AngularJS y asignaciones a window.location.

Resolución de módulos consciente del bundler

Reconoce estructuras de bundle de Webpack y Browserify, extrae los módulos individuales y resuelve llamadas a require() y exports a través de límites entre módulos.

Análisis de página completa

Analiza todos los scripts de la página como una unidad única — resolviendo globales definidos en etiquetas de script inline y usados en archivos JavaScript externos.

Published Research

Revisado por pares y publicado en una revista

Sigalov, D., Gamayunov, D. "Finding Server-Side Endpoints with Static Analysis of Client-Side JavaScript." ESORICS 2023 Workshops, LNCS vol. 14399, pp. 442–458. Springer, 2024.

Primer método que aplica análisis estático no trivial del JavaScript del cliente para descubrir endpoints de servidor en escaneos de seguridad de caja negra. Publicado en el European Symposium on Research in Computer Security y ampliado en un artículo de revista completo en el Journal of Information Security and Applications de Elsevier. Investigación de Daniil Sigalov y Dennis Gamayunov (Universidad Estatal de Moscú Lomonosov / SolidSoft LLC).

View on Springer →

Evaluation results

En OWASP Juice Shop — una aplicación de página única que envía todo el código cliente de la API a usuarios no autenticados — nuestro análisis encontró 36 endpoints de servidor. El mejor crawler dinámico encontró 13.

En MyBB encontramos 77 endpoints. El siguiente mejor resultado fue 68 (Arachni).

Probamos cinco escáneres de la industria — Acunetix, Burp Scanner, HCL AppScan, Detectify y PT BlackBox Scanner — contra un benchmark con 17 endpoints (14 ocultos). Ninguno encontró endpoints ocultos. Nuestro prototipo encontró los 17.

Los resultados varían según la complejidad de la aplicación. En WebGoat, cuyo JS del cliente usa herencia de clases y bundlers AMD más allá de nuestro soporte actual, el mejor crawler dinámico (Arachni) encontró 78 endpoints frente a 12 del análisis estático. Por eso usamos ambos métodos juntos.

El análisis se completó en menos de 30 segundos por página en todos los benchmarks. El análisis de la aplicación completa de MyBB (la ejecución más larga) tomó 5 minutos.

Los componentes open source y los datos completos del experimento están disponibles públicamente para su verificación.

Why It Matters

Por qué importan los endpoints ocultos

Cada endpoint que tu escáner pasa por alto es un endpoint que no recibe ninguna prueba de vulnerabilidades. Se queda en producción, sin probar, hasta que alguien lo encuentra.

Endpoints faltantes a menudo significan controles de acceso faltantes

Los paneles de administración, las funciones autenticadas y las interfaces de depuración accedidas a través de endpoints ocultos con frecuencia carecen de verificaciones de autorización en el servidor — la interfaz era la única barrera. Cuando un escáner encuentra y prueba estos endpoints, aparecen vulnerabilidades de Broken Access Control. Cuando no los encuentra, no aparecen. Broken Access Control ha sido la categoría nº1 del OWASP Top 10 desde 2021.

OWASP Top 10 #1 since 2021

Un descubrimiento incompleto significa cobertura incompleta

En nuestras pruebas de referencia, el mejor crawler dinámico encontró 13 endpoints en una aplicación de página única donde había 36. Esos 23 endpoints no probados incluían rutas de API para carga de archivos, administración de usuarios y exportación de datos — funcionalidad activa en el servidor que aceptaba solicitudes sin autenticar.

Best crawler found 13 of 36 endpoints

Tu alcance de cumplimiento tiene un punto ciego

PCI DSS 4.0.1, SOC 2 e ISO 27001 exigen pruebas de seguridad de aplicaciones web. Estos marcos asumen que tu escáner está probando toda la aplicación. Si el descubrimiento de endpoints es incompleto, tu alcance de pruebas también lo es — y ninguna auditoría detectará la brecha, porque los endpoints faltantes no aparecen en ningún informe.

Affected frameworks PCI DSS · SOC 2 · ISO 27001
Comparison

Qué encuentra cada método de descubrimiento

Capacidad de descubrimiento Rastreo dinámico Coincidencia de URLs por regex Análisis estático de SolidPoint
Enlaces HTML y formularios Yes N/A Yes
Solicitudes JS activables desde la UI Yes Partial Yes
Código muerto (funciones nunca invocadas) No Partial Yes
Endpoints tras autenticación (paneles de administración) With credentials * Partial Yes
URLs construidas desde variables en código muerto No No Yes
Métodos de clases sin instanciar No No Yes
Cadenas de llamadas en código no activable (3–5 niveles) No No Yes

* Solo con credenciales válidas para ese rol. Sin autenticación, los crawlers dinámicos pasan estos completamente por alto.

Transparency

Lo que aún no cubrimos

El análisis estático de JavaScript complementa el rastreo dinámico — no lo reemplaza. Nuestro analizador trabaja junto con el rastreo con navegador headless y el rastreo estático tradicional. Juntas, las tres capas producen el mapa de superficie de ataque más completo.

Algunos patrones de JavaScript siguen siendo desafiantes para el análisis estático: sistemas de eventos específicos de frameworks complejos, jerarquías de herencia de clases y endpoints construidos enteramente a partir de datos del DOM en tiempo de ejecución. Estamos ampliando activamente la cobertura en estas áreas.

Empieza hoy a potenciar tus pruebas de seguridad de aplicaciones con nosotros

Probar gratis Solicitar demo