Skip to main content

Comment atténuer les vulnérabilités SSRF en Go

Écrit par
GoLang Logo

10 décembre 2024

0 minutes de lecture

La sécurisation des requêtes HTTP est essentielle lors du développement d’applications Go afin de prévenir les vulnérabilités telles que les attaques de type Server-Side Request Forgery (SSRF). Une attaque SSRF se produit lorsqu’un attaquant manipule un serveur pour lui faire envoyer des requêtes imprévues, pouvant ainsi accéder à des services internes ou à des données sensibles.

Nous allons voir comment sécuriser les requêtes HTTP à l’aide de techniques d’analyse et de validation des URL, et présenter un exemple de code pour renforcer le gestionnaire de requêtes HTTP GET http.Get.

Voici le code du gestionnaire de route HTTP qui envoie des requêtes HTTP vers le domaine de l’utilisateur afin de récupérer une image (simplifié par souci de concision), dans une fonction appelée downloadAndResize :

func downloadAndResize(tenantID, fileID, fileSize string) error {
	// ...

	downloadResp, err := http.Get(info.Download)
	if (err != nil) {
		panic(err)
	}

	// ...
}

Atténuer les vulnérabilités SSRF dans le code Go

Pour atténuer les vulnérabilités SSRF dans les applications Go, les développeurs doivent s’attacher à valider et à assainir les entrées, et comprendre comment construire des URL de manière sécurisée afin de ne pas manipuler le domaine obtenu.

Les attaques SSRF exploitent souvent une validation insuffisante des entrées, ce qui permet aux attaquants de manipuler les URL et de rediriger les requêtes vers des destinations imprévues. En mettant en place une validation et un assainissement rigoureux des entrées, les développeurs peuvent réduire considérablement le risque d’attaques SSRF.

Valider les entrées tenantID et fileID

Dans notre application Go vulnérable, tenantID et fileID sont extraits de la chaîne de requête sans aucune validation. Cette absence de validation ouvre la voie aux attaques SSRF.

Examinons le code Go suivant, qui valide les entrées afin de s’assurer que ces paramètres peuvent être utilisés en toute sécurité :

func isValidTenantID(tenantID string) bool {
	// Implement a regex pattern to validate tenantID format
	// Example: only allow alphanumeric characters
	validTenantIDPattern := `^[a-zA-Z0-9]+$`
	matched, _ := regexp.MatchString(validTenantIDPattern, tenantID)
	return matched
}

func isValidFileID(fileID string) bool {
	// Implement a regex pattern to validate fileID format
	// Example: only allow alphanumeric characters and hyphens
	validFileIDPattern := `^[a-zA-Z0-9-]+$`
	matched, _ := regexp.MatchString(validFileIDPattern, fileID)
	return matched
}

Pourquoi limiter les requêtes sortantes aux hôtes de confiance

Une autre stratégie efficace pour atténuer les vulnérabilités SSRF consiste à limiter les requêtes sortantes aux hôtes de confiance. Pour cela, vous pouvez tenir à jour une liste d’autorisation des hôtes autorisés et vérifier que l’hôte de destination de chaque requête figure sur cette liste.

Voici un exemple de mise en place de restrictions sur les hôtes dans la fonction downloadAndResize :

func isTrustedHost(host string) bool {
	// Define a list of trusted hosts
	trustedHosts := []string{"localtest.me", "example.com"}
	for _, trustedHost := range trustedHosts {
		if host == trustedHost {
			return true
		}
	}
	return false
}

func downloadAndResize(tenantID, fileID, fileSize string) error {
	urlStr := fmt.Sprintf("http://%s.%s/storage/%s.json", tenantID, baseHost, fileID)
	parsedURL, err := url.Parse(urlStr)
	if err != nil {
		panic(err)
	}

	if !isTrustedHost(parsedURL.Hostname()) {
		return fmt.Errorf("untrusted host: %s", parsedURL.Hostname())
	}

	// Proceed with the rest of the function
	// ...
}

En définissant une liste d’hôtes autorisés comme mesure de sécurité, nous nous assurons que l’application Go n’envoie des requêtes HTTP qu’à une liste fermée d’hôtes prédéfinis et de confiance, ce qui réduit encore l’impact d’une attaque SSRF.

Pourquoi adopter une approche de développement axée sur la sécurité

Adopter une approche axée sur la sécurité est essentiel pour créer des applications robustes et sécurisées, et Go ne fait pas exception. Cela implique d’intégrer les considérations de sécurité à chaque étape du cycle de vie du développement logiciel, de la conception au déploiement.

En donnant la priorité à la sécurité, les développeurs peuvent :

  • Réduire le risque d’incidents de sécurité et de fuites de données.

  • Protéger les données des utilisateurs et préserver leur confiance.

  • Respecter les réglementations et les normes du secteur.

  • Réduire le coût et l’impact des incidents de sécurité.

En suivant ces bonnes pratiques et en utilisant des ressources comme l’aide-mémoire de sécurité Go, les développeurs peuvent renforcer la sécurité de leurs applications Go et se protéger contre des menaces telles que les attaques SSRF.

Renforcer la sécurité avec Snyk Code

Nous avons vu comment se protéger contre les vulnérabilités SSRF et pourquoi les développeurs doivent valider et assainir les entrées utilisateur, limiter les requêtes sortantes aux hôtes de confiance et utiliser des listes d’autorisation pour contrôler les domaines accessibles. En outre, des outils de sécurité comme Snyk Code peuvent aider à détecter et à corriger ces vulnérabilités dès les premières étapes du développement.

Pour renforcer davantage la sécurité de votre application, pensez à utiliser Snyk Code pour effectuer une analyse statique. Snyk Code peut détecter les vulnérabilités SSRF et d’autres problèmes de sécurité dans votre code Go avant le déploiement. En intégrant Snyk à votre IDE ou à votre dépôt, vous pouvez détecter les vulnérabilités rapidement et garantir la sécurité de votre application.

Pour découvrir d’autres bonnes pratiques de sécurité en Go, consultez l’aide-mémoire de sécurité Go et apprenez à conteneuriser vos applications en toute sécurité avec Docker.

En appliquant ces techniques et en utilisant des outils comme Snyk, vous pouvez protéger vos applications Go contre les attaques SSRF et d’autres menaces de sécurité.

Snyk est-il compatible avec d’autres langages de programmation ?

Snyk est un outil polyvalent qui prend en charge un large éventail de langages de programmation, ce qui en fait un atout essentiel pour les développeurs travaillant avec des piles technologiques variées. Que vous développiez en JavaScript, Python, Java, Ruby, PHP ou dans d’autres langages, Snyk propose des solutions de sécurité complètes adaptées à chaque écosystème.

Cela comprend :

  • JavaScript et TypeScript : avec Snyk, vous pouvez analyser vos applications Node.js pour détecter les vulnérabilités dans votre code et vos dépendances.

  • Python : Snyk aide à détecter les vulnérabilités dans les packages Python et fournit des conseils concrets pour les corriger.

  • Java : grâce à l’intégration de Snyk avec Maven et Gradle, les développeurs Java peuvent sécuriser leurs applications en détectant et en corrigeant les vulnérabilités dans leurs dépendances.

  • Ruby : les développeurs Ruby peuvent utiliser Snyk pour analyser leurs fichiers Gemfile et Gemfile.lock à la recherche de vulnérabilités connues.

PHP : Snyk prend en charge Composer, ce qui permet aux développeurs PHP de sécuriser leurs projets en détectant les vulnérabilités dans leurs dépendances.

Anticipez l’avenir des assistants de programmation avec Snyk

Découvrez les assistants de programmation et comment intégrer ces outils aux workflows de développement.

Publié dans: