Sécurité des applications Go : top 10 des vulnérabilités pour débutants
\n\nGo (Golang) est l'un des langages les plus populaires pour créer des services web à forte charge, des microservices et des applications réseau. Cependant, comme tout autre langage, Go nécessite une approche attentive de la sécurité. Si vous commencez tout juste à apprendre Go, il est important de connaître les principales vulnérabilités qui peuvent guetter votre application. Dans cet article, nous allons passer en revue les 10 menaces les plus courantes et montrer comment les éviter.
\n\n1. Injections SQL (SQL Injection)
\n\nL'injection SQL est l'une des vulnérabilités les plus anciennes et les plus dangereuses. Elle se produit lorsque l'entrée utilisateur est directement insérée dans une requête SQL.
\n\nExemple de code vulnérable :
\nfunc getUser(db *sql.DB, id string) (*User, error) {\n row := db.QueryRow("SELECT * FROM users WHERE id = " + id)\n // ...\n}\n\nComment corriger :
\nUtilisez des requêtes paramétrées :
\nfunc getUser(db *sql.DB, id string) (*User, error) {\n row := db.QueryRow("SELECT * FROM users WHERE id = $1", id)\n // ...\n}\n\n2. Scripting inter-sites (XSS)
\n\nLe XSS se produit lorsque l'entrée utilisateur non échappée est affichée sur une page web. En Go, cela arrive souvent en utilisant html/template au lieu de text/template.
Exemple de code vulnérable :
\nfmt.Fprintf(w, "<p>Bonjour, %s</p>", r.URL.Query().Get("name"))\n\nComment corriger :
\nUtilisez html/template pour un échappement automatique :
tmpl := template.Must(template.New("").Parse("<p>Bonjour, {{.}}</p>"))\ntmpl.Execute(w, r.URL.Query().Get("name"))\n\n3. Falsification de requête inter-sites (CSRF)
\n\nLes attaques CSRF forcent un utilisateur à effectuer une action non désirée sur un site où il est authentifié. Les applications Go oublient souvent la protection contre CSRF.
\n\nSolution :
\nUtilisez la bibliothèque gorilla/csrf ou implémentez votre propre middleware :
import "github.com/gorilla/csrf"\n\nfunc main() {\n r := mux.NewRouter()\n r.Use(csrf.Protect([]byte("clé-de-32-octets")))\n // ...\n}\n\n4. Gestion non sécurisée des erreurs
\n\nUne erreur courante consiste à renvoyer à l'utilisateur des messages d'erreur système qui peuvent révéler la structure interne de l'application.
\n\nExemple de code vulnérable :
\nif err != nil {\n http.Error(w, err.Error(), http.StatusInternalServerError)\n}\n\nComment corriger :
\nif err != nil {\n log.Printf("Erreur : %v", err)\n http.Error(w, "Erreur interne du serveur", http.StatusInternalServerError)\n}\n\n5. Fuite d'informations via les en-têtes
\n\nPar défaut, le serveur Go peut divulguer la version de Go, le type de serveur et d'autres informations de service.
\n\nSolution :
\ntype secureHandler struct {\n next http.Handler\n}\n\nfunc (h *secureHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n w.Header().Set("X-Content-Type-Options", "nosniff")\n w.Header().Set("X-Frame-Options", "DENY")\n w.Header().Set("X-XSS-Protection", "1; mode=block")\n h.next.ServeHTTP(w, r)\n}\n\n6. Mauvaise gestion des goroutines
\n\nLes goroutines sont un outil puissant de Go, mais leur mauvaise utilisation peut entraîner des conditions de course (race conditions) et des fuites de mémoire.
\n\nExemple de code vulnérable :
\nvar counter int\nfor i := 0; i < 1000; i++ {\n go func() {\n counter++ // condition de course !\n }()\n}\n\nComment corriger :
\nvar mu sync.Mutex\nvar counter int\nfor i := 0; i < 1000; i++ {\n go func() {\n mu.Lock()\n counter++\n mu.Unlock()\n }()\n}\n\n7. Stockage non sécurisé des mots de passe
\n\nStocker les mots de passe en clair ou avec des hachages faibles (MD5, SHA1) est une grave erreur.<