Pruebas SSRF para herramientas de agentes que inyectan credenciales
Las pruebas SSRF para herramientas de agentes necesitan una matriz de destinos que detecte loopback, rangos privados, rebinding, redirecciones e IPv6 antes de autenticar.

Una herramienta de agente que inyecta credenciales convierte el HTTP saliente habitual en una decisión sobre los límites de seguridad. Si la herramienta acepta un destino del agente, valida un nombre de host de aspecto confiable y después deja que su cliente HTTP vaya donde indiquen el DNS y las redirecciones, habrá entregado la credencial a un servicio elegido por el atacante.
La solución no consiste en pegar una lista de bloqueo más larga en un validador de URL. Necesitas una matriz de destinos que recorra todo el ciclo de la solicitud: análisis, resolución DNS, selección de dirección, conexión, gestión de redirecciones y solo después inyección de credenciales. La prueba debe observar el par que recibió la solicitud, porque ahí es donde terminó el secreto.
La inyección de credenciales debe ocurrir después de aprobar el destino
La herramienta debe decidir si puede contactar con un destino antes de adjuntar cualquier material de autenticación. Eso incluye tokens bearer, credenciales básicas, cabeceras personalizadas, firmas de solicitudes, certificados de cliente e identidades SSH, que deben incorporarse después de comprobar el destino.
Los equipos suelen colocar la comprobación en el sitio equivocado. Validan la cadena de la URL original, construyen una solicitud con una cabecera Authorization y llaman a un ayudante HTTP cómodo con el seguimiento de redirecciones activado. El ayudante resuelve los nombres, elige IPv6 o IPv4, sigue una cabecera Location y puede reutilizar cabeceras o el estado de la conexión de formas que el código de validación nunca vio.
Ese diseño tiene una ventaja: es fácil de escribir. También deja la decisión peligrosa en manos de un componente que no sabe si la solicitud lleva una credencial.
Mantén separadas estas dos decisiones:
- ¿La URL es sintácticamente válida para la herramienta?
- ¿El destino de red concreto está aprobado para una conexión autenticada?
La primera decisión analiza el esquema, el host, el puerto, la ruta, la información de usuario y la codificación porcentual. La segunda clasifica las direcciones resueltas y controla la conexión real. Una lista de hosts permitidos puede ayudar en ambas decisiones, pero no sustituye a la segunda.
RFC 3986 deja claro el problema del análisis. El componente de autoridad tiene la forma [userinfo@]host[:port]; una cadena que contiene visualmente un nombre de host confiable antes de @ puede seguir nombrando una dirección IP posterior. RFC 3986 incluso usa esta construcción al hablar de cadenas de autoridad URI engañosas. No separes las URL manualmente ni busques un nombre confiable en la cadena original. Analiza la URL con un único analizador compatible con los estándares, rechaza la información de usuario en los destinos si la herramienta no la necesita legítimamente y lee el campo de host analizado.
El invariante de seguridad es lo bastante sencillo como para convertirlo en una prueba:
La herramienta no debe enviar ningún byte autenticado hasta haber aprobado el par conectado y la autoridad de la solicitud correspondiente.
«Byte autenticado» incluye la línea de solicitud o la cabecera Host solo cuando esos valores revelan un secreto por sí mismos. En la mayoría de los casos HTTP, el límite importante es la cabecera que contiene la credencial o el contenido firmado. Sé más estricto cuando la ruta, la cadena de consulta o el cuerpo contengan una URL con capacidad, un identificador de inquilino u otro valor sensible.
Define el punto de decisión antes de escribir los casos
No puedes probar un control contra SSRF hasta poder señalar el punto exacto donde toma la decisión de permitir o denegar. «Antes de la solicitud» es demasiado impreciso. Una solicitud tiene varios momentos en los que el destino puede cambiar.
Usa esta secuencia como modelo para una herramienta HTTP que inyecta credenciales:
- Analiza la URL absoluta proporcionada y rechaza los esquemas no compatibles, las autoridades malformadas, la información de usuario y los puertos que queden fuera del contrato de la herramienta.
- Resuelve el nombre de host mediante el resolver que utilizará realmente el proceso. Obtén respuestas A y AAAA, no solo la respuesta que tu máquina de desarrollo haya preferido.
- Clasifica todas las direcciones candidatas. Rechaza la solicitud si el conjunto contiene una dirección fuera de las clases de destino aprobadas, salvo que el conector pueda fijarse a una dirección aprobada.
- Abre una conexión con una dirección aprobada y verifica después la dirección del par remoto antes de escribir la credencial.
- Construye la solicitud autenticada solo después de esa verificación. Establece de forma deliberada la cabecera Host y el nombre del servidor TLS previsto.
- Trata una redirección como una solicitud nueva que empieza en el análisis, no como una continuación que hereda la confianza.
Esto exige más que comprobar hostname != "localhost". Y debe ser así. RFC 8305 describe clientes que realizan consultas AAAA y A con poca diferencia y prueban las direcciones teniendo en cuenta la preferencia por IPv6. Una suite que solo resuelve registros A puede certificar un código que falla en cuanto aparece un registro AAAA accesible.
El punto de decisión también determina qué debe registrar el entorno de pruebas. En cada intento, captura:
- la URL recibida por la herramienta
- las respuestas DNS devueltas a la herramienta
- la dirección seleccionada para la conexión
- la dirección observada por el servidor receptor
- todas las cabeceras de la solicitud, con las credenciales de prueba ocultas en los informes
No uses una prueba que solo compruebe un código de estado o una excepción. Un 403 de tu servidor de captura demuestra que recibió la solicitud. Un tiempo de espera puede no demostrar nada. La afirmación que buscas es: «El receptor bloqueado no observó ninguna solicitud con credenciales».
Construye la matriz alrededor de los destinos, no de los nombres de host
Una matriz de destinos es el artefacto duradero de este trabajo. Cada fila indica una forma de entrada, la respuesta del resolver, un comportamiento opcional de redirección y el resultado esperado. Evita la deriva habitual en la que una persona prueba 127.0.0.1, otra prueba 10.0.0.1 y nadie prueba las formas extrañas que acepta el entorno de ejecución.
Empieza con una matriz pequeña que tenga un oráculo real. El ejemplo siguiente supone que public.test apunta a un receptor del entorno de pruebas clasificado como permitido, mientras que todas las demás clases de dirección deben denegarse antes de inyectar la credencial.
| Caso | URL enviada | Comportamiento DNS o de redirección | Resultado esperado |
|---|---|---|---|
| IPv4 pública | https://public.test/echo | Registro A hacia el recurso público del entorno de pruebas | Permitir y enviar la credencial de prueba |
| Loopback IPv4 | http://127.0.0.1:18080/ | Dirección literal | Denegar antes de conectar |
| Variante de loopback IPv4 | http://127.1:18080/ | Forma abreviada dependiente del analizador | Rechazar o clasificar como loopback, nunca permitir |
| Privada RFC 1918 | http://10.20.30.40/ | Dirección literal | Denegar antes de conectar |
| Privada RFC 1918 | http://172.20.30.40/ | Dirección literal | Denegar antes de conectar |
| Privada RFC 1918 | http://192.168.20.40/ | Dirección literal | Denegar antes de conectar |
| Loopback IPv6 | http://[::1]:18080/ | Dirección literal | Denegar antes de conectar |
| Link-local IPv6 | http://[fe80::1]/ | Dirección literal | Denegar antes de conectar |
| IPv6 asignada a IPv4 | http://[::ffff:127.0.0.1]/ | Dirección literal | Denegar antes de conectar |
| Respuesta DNS mixta | https://mixed.test/ | A permitida y AAAA bloqueada | Denegar o fijar la conexión a la dirección permitida |
| Nombre con rebinding | https://rebind.test/ | Primero permitido y después bloqueado | Denegar la solicitud autenticada al par bloqueado |
| Redirección a loopback | https://public.test/to-local | 302 a http://127.0.0.1:18080/ | Denegar la segunda solicitud |
| Redirección a DNS privado | https://public.test/to-private | 302 a https://internal.test/ | Resolver y denegar la segunda solicitud |
| Engaño con información de usuario | http://[email protected]/ | Host literal posterior a @ | Rechazar antes de conectar |
RFC 1918 define solo tres bloques privados IPv4: 10/8, 172.16/12 y 192.168/16. Prueba los límites, especialmente 172.15.255.255, 172.16.0.0, 172.31.255.255 y 172.32.0.0. Una comprobación de prefijo descuidada suele bloquear todo 172/8, lo que rompe puntos de conexión públicos legítimos, o solo 172.16/16, lo que deja fuera la mayor parte del rango privado asignado.
No confundas esta tabla con una política de producción universal. Algunas herramientas internas deben poder contactar con un servicio privado específico. Si ese es tu requisito de producto, dale a ese servicio una regla explícita con un nombre de host, un puerto y una comprobación de identidad limitados. No conviertas «las direcciones privadas están bien en nuestra oficina» en el valor predeterminado para cualquier destino elegido por un agente.
Las pruebas del análisis de URL detectan errores antes que el DNS
El analizador debe identificar el host que utilizará el conector. Parece obvio hasta que una prueba revela que un componente normaliza la entrada de forma distinta a otro.
Incluye estos casos en una suite dedicada al análisis. Deben ejecutarse sin DNS ni conexión de red:
http://[email protected]/admin
http://127.0.0.1.nip.example/
http://[::1]/
http://[::ffff:7f00:1]/
http://0177.0.0.1/
http://2130706433/
http://127.0.0.1%2f.example/
http://public.test:[email protected]/
http://public.test./
El resultado esperado no siempre es «esta cadena exacta debe analizarse como loopback». Las bibliotecas URI y URL difieren en las formas numéricas IPv4 antiguas, los identificadores de zona y las codificaciones porcentuales no válidas. Tu prueba debe expresar la propiedad de seguridad: si el entorno acepta la entrada y la conectaría con una dirección bloqueada, la herramienta debe denegarla. Si el entorno la rechaza, también está bien.
La diferencia importa porque muchos equipos escriben primero un filtro de host personalizado y después entregan la URL sin cambios a otra biblioteca. El filtro puede considerar 2130706433 un nombre registrado desconocido, mientras que el conector lo interpreta como 127.0.0.1. Acabas de probar dos analizadores y has confiado en la respuesta más segura.
Usa la misma representación analizada para la validación y la conexión. Cuando no sea posible, haz que el conector final informe de la dirección numérica del par que seleccionó y realiza una última comprobación de la clase de dirección antes de que las credenciales salgan del proceso.
También debes probar la normalización de los nombres de host. Un punto final en public.test. hace referencia al mismo nombre DNS que public.test en el uso DNS habitual, pero las listas de permitidos simples suelen comparar las cadenas sin procesar. Los nombres de host internacionalizados añaden otro punto de desacuerdo. Convierte una sola vez a la representación canónica de nombre de host del entorno de ejecución y compara un nombre DNS respetando los límites entre etiquetas. Una comprobación de sufijo como endsWith("trusted.example") acepta untrusted.example y trusted.example.attacker.test; ninguno es un subdominio confiable.
Las pruebas de rebinding DNS deben forzar la segunda consulta
El rebinding DNS es un fallo de sincronización. La consulta inicial devuelve una dirección aceptable. Una consulta posterior para el mismo nombre devuelve loopback, una dirección privada u otro destino bloqueado. Si la validación y la conexión no usan el mismo resultado de resolución, un atacante puede superar la primera comprobación y dirigir la segunda.
Un recurso útil necesita un pequeño servidor DNS autoritativo bajo tu control y dos receptores HTTP. Uno es el recurso permitido. El otro es un recurso bloqueado que registra si recibió la cabecera Authorization de prueba. Dale al servidor DNS una secuencia de respuestas para rebind.test:
query 1: rebind.test. A 198.51.100.20
query 2: rebind.test. A 127.0.0.1
query 1: rebind.test. AAAA 2001:db8::20
query 2: rebind.test. AAAA ::1
Usa direcciones reservadas para el entorno de pruebas y asigna el receptor permitido en la red de pruebas según sea necesario. Las direcciones de documentación con apariencia pública de este ejemplo son etiquetas del recurso de pruebas, no puntos de conexión que la prueba deba contactar en Internet.
Ejecuta ahora dos variantes. En la primera, haz que la herramienta realice su propia consulta de validación y después llama a una biblioteca HTTP que resuelva los nombres por separado. Si la implementación tiene la brecha que buscas, el receptor bloqueado debería recibir la credencial. En la segunda, configura el camino de conexión para usar la dirección resuelta aprobada, conserva el nombre de host original solo para Host y la verificación del nombre TLS, y comprueba que el receptor bloqueado no observe nada.
La caché puede ocultar este problema. Una caché del resolver, un grupo de conexiones o la caché del sistema operativo pueden convertir la segunda respuesta en un evento que nunca ocurre. El entorno de pruebas debe ofrecer controles de caché, cerrar las conexiones inactivas entre ejecuciones, usar un nombre de host nuevo en cada ejecución cuando sea necesario y registrar cada consulta DNS. Si una prueba de rebinding pasa sin confirmar dos consultas distintas, no ha probado el rebinding.
No resuelvas el problema confiando en el TTL del DNS. El TTL es una indicación para la caché, no una afirmación de que un nombre seguirá siendo seguro entre la validación y la conexión. El código debe llevar la dirección aprobada hasta la conexión o verificar el par después de abrir el socket.
Las redirecciones son decisiones independientes sobre el destino
Una redirección cambia el destino. Puede cambiar el esquema, el host, el puerto, la ruta o los cuatro elementos. Tratarla como una continuación confiable es la forma en que una URL pública aparentemente segura se convierte en una solicitud a 127.0.0.1, un servicio de metadatos de instancia, un router o un plano de control interno.
Desactiva el seguimiento automático de redirecciones en el transporte que utilice la solicitud con credenciales. Lee la respuesta de redirección, aplica un límite moderado, analiza el valor de Location respecto a la URL actual según las reglas de resolución de URL de la biblioteca y vuelve a ejecutar la decisión completa sobre el destino.
Tu recurso de redirecciones debe incluir al menos estos comportamientos:
- Una URL pública devuelve un 302 a un literal loopback IPv4.
- Una URL pública devuelve un 307 a un nombre de host que resuelve en una dirección IPv4 privada.
- Una URL pública devuelve una Location relativa como
/next, que debe permanecer en la autoridad ya aprobada después de la resolución normal. - Una URL pública devuelve una Location relativa al esquema como
//other.test/path, que cambia la autoridad y necesita una validación completa. - Una URL pública devuelve una cadena de redirecciones en la que el primer salto está permitido y uno posterior está bloqueado.
Los códigos de estado importan. Un 301, 302 o 303 puede hacer que los clientes cambien un método distinto de GET a GET. Un 307 o 308 está pensado para conservar el método y el cuerpo. No dependas del tratamiento predeterminado de una biblioteca cuando haya una solicitud POST firmada o una escritura autenticada con bearer. Registra el método, el hash del cuerpo, la cabecera Host y la cabecera Authorization en cada recurso de redirección.
Eliminar Authorization cuando cambia la autoridad es una buena defensa, pero no hace que la validación del destino sea opcional. Una solicitud sin cabecera Authorization aún puede llevar una URL firmada en la ruta, un certificado de cliente, cookies o un cuerpo sensible. Una redirección al mismo host también puede apuntar a un servicio local si el DNS cambia entre saltos.
Este es un punto en el que la prueba debe ser deliberadamente sencilla. Haz que el receptor de la redirección bloqueada devuelva 200. Si tu afirmación solo espera un error del cliente, un cliente que siga redirecciones puede realizar correctamente la solicitud SSRF y tu prueba la considerará aprobada por el motivo equivocado. Comprueba el número de solicitudes capturadas por el receptor y el estado de las credenciales capturadas.
IPv6 es una superficie SSRF de primer nivel
La omisión de IPv6 suele ser accidental. Un desarrollador prueba 127.0.0.1, bloquea los rangos RFC 1918 y publica código que considera [::1] un nombre de host exótico. Los clientes modernos pueden consultar registros AAAA junto con registros A, y una ruta IPv6 puede ganar incluso cuando las pruebas IPv4 parecen correctas.
RFC 4291 identifica ::1/128 como la dirección loopback IPv6 y ::/128 como la dirección no especificada. También define las direcciones unicast link-local bajo fe80::/10. Estas son clases de dirección que nunca deben convertirse accidentalmente en un destino autenticado elegido por un agente.
Prueba estas categorías explícitamente:
| Clase de dirección | Ejemplo | Resultado predeterminado esperado |
|---|---|---|
| No especificada | [::] | Denegar |
| Loopback | [::1] | Denegar |
| Link-local | [fe80::1] | Denegar |
| Local única | [fc00::1], [fd12:3456::1] | Denegar salvo aprobación explícita |
| Multidifusión | [ff02::1] | Denegar |
| Loopback IPv4 asignada a IPv6 | [::ffff:127.0.0.1] | Denegar |
| Privada IPv4 asignada a IPv6 | [::ffff:192.168.1.10] | Denegar |
La clasificación de direcciones debe operar sobre la dirección binaria, no sobre su representación escrita. Una misma dirección puede aparecer en forma IPv6 comprimida o expandida. Una comparación de cadenas con ::1 no detecta 0:0:0:0:0:0:0:1. Analizar primero la dirección con un tipo IP real es la parte poco vistosa que evita esta categoría de errores.
Los identificadores de ámbito también necesitan una regla clara. Una entrada como [fe80::1%25en0] contiene una zona de interfaz después de la codificación porcentual. La mayoría de las herramientas deben rechazar los destinos literales con ámbito introducidos por un agente, en lugar de intentar decidir qué interfaz local es segura. Si el producto tiene un caso de uso válido en una red local, convierte la elección de interfaz en una configuración explícita propiedad del usuario, nunca en un detalle de la URL proporcionado por el agente.
Las respuestas A y AAAA mixtas requieren una decisión firme. Si el resolver devuelve una dirección IPv4 permitida y otra IPv6 bloqueada, el valor predeterminado más seguro es denegar. Si la disponibilidad exige usar la respuesta permitida, el conector debe fijar el socket a esa dirección y no volver a entregar el nombre de host a un resolver. «Preferimos IPv4» no es un control. Las bibliotecas de red, los sistemas operativos y las carreras de conexión pueden elegir otra dirección.
Ejecuta la matriz dentro de un entorno aislado
No dirijas las pruebas SSRF a los servicios localhost reales de tu portátil ni a un punto de conexión de metadatos en la nube. Buscas pruebas, no una tarde estresante. Coloca el resolver y todos los receptores en una red de pruebas aislada, usa credenciales desechables y haz que los receptores registren su propia dirección y las cabeceras recibidas.
Un entorno sencillo tiene cuatro actores:
- Un ejecutor de pruebas que invoca la herramienta con una URL y una referencia a una credencial desechable.
- Un servidor DNS controlable que puede devolver respuestas A y AAAA en un orden programado.
- Un recurso HTTP permitido que registra las solicitudes autenticadas correctas.
- Un recurso HTTP bloqueado que registra cualquier conexión o solicitud como un fallo de la prueba.
Dale al recurso bloqueado un cuerpo de respuesta que haga evidentes las fugas en los registros locales, pero no imprimas nunca un token completo. Por ejemplo, puede devolver la dirección del par, el método de solicitud, la cabecera Host y un valor booleano que indique si estaba presente Authorization. El ejecutor compara esas pruebas con la fila esperada de la matriz.
El formato del resultado debe ser lo bastante sencillo como para inspeccionarlo en CI:
case=redirect_to_loopback
submitted=https://public.test/to-local
resolved=198.51.100.20
redirect=http://127.0.0.1:18080/
decision=deny
allowed_requests=0
blocked_connections=0
blocked_credentials=0
Un fallo debe conservar los mismos campos y añadir el par real. Así una regresión imprecisa se convierte en un informe útil:
case=rebind_ipv6
submitted=https://rebind.test/export
validation_answer=2001:db8::20
connected_peer=::1
blocked_credentials=1
result=FAIL
El informe identifica el error de inmediato: el código aprobó una respuesta DNS y se conectó a otra. También indica si la credencial cruzó el límite, que es el riesgo que te importa.
Si tu herramienta admite la configuración de un proxy, añade filas de proxy a la matriz. Un proxy HTTP cambia el destino de la conexión TCP, mientras que CONNECT puede hacer que el proxy llegue igualmente a un destino elegido por el atacante. Decide si el propio proxy es un transporte confiable y si la herramienta valida la autoridad final. Una prueba de proxy que solo comprueba la dirección del proxy puede certificar un relay abierto hacia destinos internos.
Mantén separadas la autoridad y el destino en la implementación
TLS hace que este problema se confunda con facilidad. Para conectarse de forma segura a un nombre de host, la herramienta puede necesitar abrir un socket hacia una dirección numérica aprobada mientras presenta el nombre de host original y aprobado como nombre del servidor TLS y cabecera HTTP Host. Son campos distintos con funciones distintas.
El par numérico responde a «¿Adónde va este socket?». El nombre del servidor TLS responde a «¿Qué identidad de certificado debe demostrar este servidor?». La cabecera Host responde a «¿A qué autoridad HTTP se dirige esta solicitud?». La implementación debe mantener explícitos los tres valores, en lugar de dejar que una API HTTP de conveniencia los deduzca de una cadena URL mutable.
Esta separación también deja al descubierto una recomendación incorrecta que sigue siendo popular: resolver una vez y sustituir después el nombre de host de la URL por la dirección numérica. Puede evitar una segunda consulta DNS, pero puede romper la validación del certificado TLS, el alojamiento virtual y los esquemas de solicitudes firmadas. Los desarrolladores suelen responder desactivando la validación del certificado o debilitando las comprobaciones del host. Eso es peor que el error original.
En su lugar, usa un transporte que permita marcar la dirección aprobada para la conexión mientras conserva una validación TLS estricta para el nombre de host original. Después del handshake, confirma que el par del socket es la dirección aprobada. Si tu entorno no ofrece esos controles, no afirmes que evita el rebinding DNS en solicitudes autenticadas de agentes. Incluye esa limitación en los límites del producto y evita inyectar credenciales en destinos elegidos por agentes.
SSH tiene la misma estructura, aunque no usa redirecciones HTTP. Resuelve y clasifica el host solicitado, fija la conexión a la dirección aprobada y verifica la clave del host frente a la identidad prevista. Un aviso de clave de host o una regla permisiva de hosts conocidos no es una política de destino.
Sallyport mantiene las credenciales dentro de su bóveda cifrada y ejecuta las acciones HTTP y SSH por su cuenta, en lugar de entregar el material secreto al agente. Ese límite solo se mantiene si la capa de acciones aplica controles de destino antes de usar una credencial almacenada.
Convierte la matriz en un bloqueo de publicación, no en un documento de seguridad
Una matriz de destinos solo sirve cuando se ejecuta contra el mismo camino de solicitud que llegará a producción. Una prueba unitaria de isPrivateIp() no prueba el resolver del cliente HTTP, el código de redirecciones, el comportamiento del proxy ni el grupo de conexiones. Conserva las pruebas unitarias, pero haz obligatoria la suite del entorno aislado cada vez que actualices la biblioteca de transporte, el analizador de URL, la configuración del resolver o el código de inyección de credenciales.
Añade filas cuando corrijas un error. No reduzcas un incidente doloroso a una afirmación general como «mejorar la validación SSRF». Conserva la entrada exacta, la secuencia DNS, la respuesta de redirección y la ausencia esperada de credenciales. Los futuros responsables necesitan esa experiencia convertida en código ejecutable.
Revisa los fallos por categoría. Las discrepancias del analizador apuntan a un tratamiento duplicado de las URL. Un receptor bloqueado que ve una conexión TCP pero ninguna solicitud puede indicar que validaste demasiado tarde, aunque no se haya filtrado ningún token. Si un receptor bloqueado ve una cabecera Authorization, el invariante ha fallado y la publicación debe detenerse.
El trabajo compensa porque cambia la pregunta que hace el equipo. Deja de preguntar si un nombre de host parecía externo. Pregunta qué par recibió una solicitud autenticada, cómo se seleccionó y si la prueba puede demostrarlo. Si no puedes responder a partir de la salida de la prueba, la herramienta todavía tiene un punto ciego frente a SSRF.
FAQ
¿Basta con permitir determinados nombres de host para evitar SSRF en una herramienta de agente?
No. Un nombre de host solo es una entrada para la resolución, y un nombre que parece inofensivo puede resolverse en una dirección local o privada cuando el cliente se conecta. Prueba el conjunto de direcciones resueltas y el par real al que se conectó la herramienta, no solo el texto original que proporcionó el agente.
¿Debe un cliente HTTP reenviar credenciales al seguir redirecciones?
Trata cada redirección como una solicitud a un destino nuevo. Valida la URL nueva, vuelve a resolverla, aplica la misma decisión sobre el destino y añade las credenciales solo después de que pase la validación. Si la redirección cambia la autoridad, quitar la cabecera Authorization es una medida sensata, pero no suficiente.
¿Qué direcciones IPv6 debe bloquear una prueba de SSRF?
Sí. Bloquea o clasifica explícitamente el loopback IPv6 (::1), la dirección no especificada (::), las direcciones link-local (fe80::/10), las direcciones locales únicas (fc00::/7), las multidifusión y las formas IPv4 asignadas a IPv6. Una suite que solo prueba direcciones IPv4 con puntos deja un punto ciego importante.
¿Cómo puedo probar el rebinding de DNS de forma segura?
El rebinding de DNS ocurre cuando el nombre supera una resolución inicial, pero después devuelve otra dirección, a menudo justo antes de la conexión. Usa un dispositivo DNS controlable que responda primero con una dirección permitida y después con una bloqueada. Luego verifica que la herramienta no envíe una solicitud autenticada al par bloqueado.
¿Puedo validar el DNS una vez y dejar que la biblioteca HTTP se conecte normalmente?
No. Comprobar un resultado de resolución y dejar después que la biblioteca HTTP resuelva el nombre de nuevo crea una brecha de tiempo entre la comprobación y el uso. Resuelve el nombre, clasifica todos los candidatos y conéctate usando la dirección aprobada, o verifica la dirección del par después de conectar y antes de enviar las credenciales.
¿Qué es una matriz de destinos para probar SSRF?
Una matriz de destinos es una lista de entradas URL, respuestas DNS, destinos de redirección y decisiones de seguridad esperadas. Convierte afirmaciones imprecisas como «bloqueamos las IP privadas» en pruebas repetibles que detectan errores del analizador, formatos de dirección alternativos y cambios en el comportamiento de las bibliotecas.
¿Las herramientas de agentes que solo leen necesitan protección contra SSRF?
Sí, si la herramienta adjunta un secreto, un certificado de cliente, una solicitud firmada o cualquier credencial con autoridad más allá del agente. Una solicitud que solo lee documentación pública tiene un impacto potencial menor, pero aun así debe evitar el acceso no previsto a servicios locales.
¿Qué debe ocurrir cuando el DNS devuelve direcciones públicas y privadas a la vez?
Falla de forma segura. Si el resolver devuelve una mezcla de direcciones permitidas y bloqueadas, un cliente HTTP normal puede elegir la bloqueada por el orden de las direcciones o la preferencia por IPv6. Una herramienta que inyecta credenciales debe rechazar las respuestas mixtas, salvo que controle la dirección aprobada a la que se conecta.
¿Basta con bloquear los rangos RFC 1918 para defenderse de SSRF?
No. Los rangos privados son solo una categoría. El loopback, las direcciones link-local, el espacio de NAT de nivel de operador, los rangos de documentación, las direcciones no especificadas, la multidifusión, los valores IPv4 asignados a IPv6, las redirecciones y los cambios de DNS también necesitan un tratamiento deliberado.
¿Cómo puedo demostrar que una herramienta de agente nunca envió una credencial a un destino bloqueado?
Usa un servidor de captura inofensivo que registre el par remoto, la ruta de la solicitud, la cabecera Host y si llegó una cabecera Authorization. Cárgalo con un token de prueba desechable que no tenga acceso fuera del entorno de pruebas. Un buen informe de error indica qué destino recibió el token, no solo que una solicitud devolvió 200.