
Preuve de concept et analyse de CVE-2025-46721, une vulnérabilité CSRF dans la bibliothèque nosurf Go due à des vérifications de même origine non fonctionnelles, avec une démonstration d'exploit fonctionnelle.
Toutes les versions de nosurf antérieures à 1.2.0 n'appliquaient pas les vérifications de même origine pour les requêtes entrantes.
Cela venait du fait qu'elles s'appuyaient sur le champ .URL.Scheme du type net/http.Request de la bibliothèque standard de Go
pour d'abord s'assurer que la requête est servie via HTTPS, et ensuite seulement appliquer les vérifications de même origine.
Le champ Scheme mentionné n'est pas renseigné par le serveur HTTP de Go pour les requêtes entrantes :
Pour les requêtes serveur, l'URL est analysée à partir de l'URI fournie sur la ligne de requête telle que stockée dans RequestURI. Pour la plupart des requêtes, les champs autres que Path et RawQuery seront vides.
car dans le cas général, Go ne peut pas déterminer si la requête se fait via TLS (en raison de la possible présence d'un proxy inverse terminant TLS, etc.).
Cela peut permettre à des attaquants d'émettre des requêtes cross-origin non sûres vers votre site web.
En plus d'implémenter des vérifications de même origine, nosurf protège également contre les CSRF à l'aide d'un modèle de cookie à double soumission.
Cela signifie que, pour réussir une requête cross-origin de mutation,
l'attaquant a également besoin du contrôle sur le contenu d'une page de votre site web,
ou d'un sous-domaine de votre site web.
Cela peut être réalisé via XSS, ou si vous donnez intentionnellement le contrôle du contenu HTML pour des utilisateurs sur votre site web
(par exemple, vous êtes un fournisseur d'hébergement example.com qui permet aux utilisateurs d'héberger leurs sites sur alice.example.com).
La PoC dans ce dépôt démontre une telle attaque dans ce dernier cas, où l'attaquant a le contrôle du contenu sur un sous-domaine du domaine principal du site.
Nécessite Go et Caddy. Lancez les serveurs manuellement :
$ go run attacker.go & go run target.go & caddy run
ou via Process Compose :
$ process-compose
Visitez https://attacker.target.localhost.
Cliquez sur le bouton pour soumettre le formulaire à https://target.localhost et observez que la requête aboutit.
Un correctif pour ce problème a été publié dans nosurf 1.2.0.
Merci à Patrick O'Doherty d'avoir signalé le problème.