Sicherheit von Go-Anwendungen: Top-10-Schwachstellen für Anfänger
\n\nGo (Golang) ist eine der beliebtesten Sprachen für die Erstellung hochlastiger Webdienste, Microservices und Netzwerkanwendungen. Wie jede andere Sprache erfordert jedoch auch Go eine sorgfältige Herangehensweise an die Sicherheit. Wenn Sie gerade erst anfangen, Go zu lernen, ist es wichtig, die grundlegenden Schwachstellen zu kennen, die Ihre Anwendung bedrohen können. In diesem Artikel besprechen wir die 10 häufigsten Bedrohungen und zeigen, wie Sie diese vermeiden können.
\n\n1. SQL-Injection
\n\nSQL-Injection ist eine der ältesten und gefährlichsten Schwachstellen. Sie tritt auf, wenn Benutzereingaben direkt in eine SQL-Abfrage eingefügt werden.
\n\nBeispiel für anfälligen Code:
\nfunc getUser(db *sql.DB, id string) (*User, error) {\n row := db.QueryRow("SELECT * FROM users WHERE id = " + id)\n // ...\n}\n\nSo beheben Sie es:
\nVerwenden Sie parametrisierte Abfragen:
\nfunc getUser(db *sql.DB, id string) (*User, error) {\n row := db.QueryRow("SELECT * FROM users WHERE id = $1", id)\n // ...\n}\n\n2. Cross-Site Scripting (XSS)
\n\nXSS tritt auf, wenn nicht maskierte Benutzereingaben auf einer Webseite angezeigt werden. In Go passiert dies häufig bei der Verwendung von html/template anstelle von text/template.
Beispiel für anfälligen Code:
\nfmt.Fprintf(w, "<p>Hallo, %s</p>", r.URL.Query().Get("name"))\n\nSo beheben Sie es:
\nVerwenden Sie html/template für automatische Maskierung:
tmpl := template.Must(template.New("").Parse("<p>Hallo, {{.}}</p>"))\ntmpl.Execute(w, r.URL.Query().Get("name"))\n\n3. Cross-Site Request Forgery (CSRF)
\n\nCSRF-Angriffe zwingen einen Benutzer dazu, eine unerwünschte Aktion auf einer Website auszuführen, bei der er angemeldet ist. Go-Anwendungen vergessen oft den Schutz vor CSRF.
\n\nLösung:
\nVerwenden Sie die Bibliothek gorilla/csrf oder implementieren Sie Ihre eigene Middleware:
import "github.com/gorilla/csrf"\n\nfunc main() {\n r := mux.NewRouter()\n r.Use(csrf.Protect([]byte("32-Byte-Schlüssel")))\n // ...\n}\n\n4. Unsichere Fehlerbehandlung
\n\nEin häufiger Fehler ist die Rückgabe von Systemfehlermeldungen an den Benutzer, die die interne Struktur der Anwendung offenlegen können.
\n\nBeispiel für anfälligen Code:
\nif err != nil {\n http.Error(w, err.Error(), http.StatusInternalServerError)\n}\n\nSo beheben Sie es:
\nif err != nil {\n log.Printf("Fehler: %v", err)\n http.Error(w, "Interner Serverfehler", http.StatusInternalServerError)\n}\n\n5. Informationsleck durch Header
\n\nStandardmäßig kann ein Go-Server die Go-Version, den Servertyp und andere Dienstinformationen preisgeben.
\n\nLösung:
\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. Falscher Umgang mit Goroutinen
\n\nGoroutinen sind ein mächtiges Werkzeug in Go, aber ihre falsche Verwendung kann zu Race Conditions und Speicherlecks führen.
\n\nBeispiel für anfälligen Code:
\nvar counter int\nfor i := 0; i < 1000; i++ {\n go func() {\n counter++ // Race Condition!\n }()\n}\n\nSo beheben Sie es:
\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. Unsichere Passwortspeicherung
\n\nDie Speicherung von Passwörtern im Klartext oder mit schwachen Hashes (MD5, SHA1) ist ein grober Fehler.<