
Prueba de concepto y análisis de CVE-2025-46721, una vulnerabilidad CSRF en la librería nosurf de Go debido a comprobaciones de mismo origen no funcionales, con una demostración funcional del exploit.
Todas las versiones de nosurf anteriores a la 1.2.0 no aplicaban verificaciones de mismo origen para las solicitudes entrantes. Esto ocurrió debido a que se confiaba en el campo .URL.Scheme del tipo net/http.Request de la biblioteca estándar de Go para primero asegurarse de que la solicitud se sirviera a través de HTTPS, y solo entonces aplicar las verificaciones de mismo origen. El mencionado campo Scheme no es completado por el servidor HTTP de Go en las solicitudes entrantes:
// For server requests, the URL is parsed from the URI // supplied on the Request-Line as stored in RequestURI. For // most requests, fields other than Path and RawQuery will be // empty.
ya que en el caso general, Go no puede determinar si la solicitud se está realizando a través de TLS (debido a la posible presencia de un proxy inverso que termina TLS, etc.).
Esto podría permitir a atacantes realizar solicitudes entre orígenes no seguras a su sitio web.
Además de implementar verificaciones de mismo origen, nosurf también protege contra CSRF utilizando un patrón de cookie de doble envío. Esto significa que, para realizar con éxito una solicitud entre orígenes mutante, el atacante también necesita tener control sobre el contenido de una página en su sitio web, o en un subdominio de su sitio web. Esto se puede lograr mediante XSS, o si usted otorga intencionalmente el control del contenido HTML a los usuarios en su sitio web (por ejemplo, usted es un proveedor de alojamiento example.com que permite a los usuarios alojar sus sitios en alice.example.com).
El PoC en este repositorio demuestra dicho ataque en el último caso, donde el atacante tiene control sobre el contenido de un subdominio del dominio principal del sitio web.
Requiere Go y Caddy. Ejecute los servidores manualmente:
$ go run attacker.go & go run target.go & caddy run
o mediante Process Compose:
$ process-compose
Visite https://attacker.target.localhost. Haga clic en el botón para enviar el formulario a https://target.localhost y observe que la solicitud se completa con éxito.
Se publicó una corrección para este problema en nosurf 1.2.0.
Gracias a Patrick O'Doherty por reportar el problema.