heygrc
Respuesta

¿Cómo puedo obtener una URL o webhook proporcionada por el usuario sin SSRF?

el equipo de heygrc

Valide el destino antes de obtenerlo: exija https, resuelva el host y rechace direcciones privadas, internas y de enlace local (incluyendo los extremos de metadatos en la nube). Prefiera una lista de permitidos cuando los destinos sean conocidos, y no siga redirecciones ciegamente. La falsificación de solicitudes del lado del servidor es un problema de validación de entrada (NIST 800-53 SI-10), y la verificación debe estar en el código que realiza la solicitud.

  1. Validar el destino

    Solo permita los esquemas que pretenda (generalmente https) y rechace direcciones en rangos privados, de loopback, de enlace local y de metadatos. Valide la dirección resuelta en el momento de la conexión, no solo la URL inicialmente, ya que el DNS puede resolverse de manera diferente entre una verificación previa y la solicitud real (vinculación DNS).

  2. Prefiera una lista de permitidos

    Si el conjunto de destinos es conocido (una lista fija de extremos de socios), utilice una lista de permitidos en lugar de aceptar URLs arbitrarias. Cuanto más estrecha sea la entrada que acepte, menos habrá que pueda salir mal.

  3. No siga redirecciones ciegamente

    Una redirección puede enviar una URL pública validada a una dirección interna en el siguiente salto. Revalide en cada redirección o desactive el seguimiento de redirecciones para destinos proporcionados por el usuario.

webhooks/send.ts+2 -1
async function send(url, payload) {-  return fetch(url, { method: 'POST', body: payload })+  // safeFetch valida la dirección RESUELTA en el momento de la conexión+  return safeFetch(url, { method: 'POST', body: payload, allowRedirects: false })}
heygrcNIST 800-53 SI-10

Validar la dirección resuelta en el momento de la conexión, no solo la URL inicialmente (que la vinculación DNS puede eludir), evita que un destino manipulado acceda a servicios internos.