Security of Go Applications: Top 10 Vulnerabilities for Beginners

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Security of Go Applications: Top 10 Vulnerabilities for Beginners

\n\n

Go (Golang) is one of the most popular languages for building high-load web services, microservices, and network applications. However, like any other language, Go requires a careful approach to security. If you are just starting to learn Go, it is important to know the main vulnerabilities that may threaten your application. In this article, we will cover the 10 most common threats and show how to avoid them.

\n\n

1. SQL Injection

\n\n

SQL injection is one of the oldest and most dangerous vulnerabilities. It occurs when user input is directly inserted into an SQL query.

\n\n

Example of vulnerable code:

\n
func getUser(db *sql.DB, id string) (*User, error) {\n    row := db.QueryRow("SELECT * FROM users WHERE id = " + id)\n    // ...\n}
\n\n

How to fix:

\n

Use parameterized queries:

\n
func getUser(db *sql.DB, id string) (*User, error) {\n    row := db.QueryRow("SELECT * FROM users WHERE id = $1", id)\n    // ...\n}
\n\n

2. Cross-Site Scripting (XSS)

\n\n

XSS occurs when unescaped user input is displayed on a web page. In Go, this often happens when using html/template instead of text/template.

\n\n

Example of vulnerable code:

\n
fmt.Fprintf(w, "<p>Hello, %s</p>", r.URL.Query().Get("name"))
\n\n

How to fix:

\n

Use html/template for automatic escaping:

\n
tmpl := template.Must(template.New("").Parse("<p>Hello, {{.}}</p>"))\ntmpl.Execute(w, r.URL.Query().Get("name"))
\n\n

3. Cross-Site Request Forgery (CSRF)

\n\n

CSRF attacks force a user to perform an unwanted action on a site where they are authenticated. Go applications often forget about CSRF protection.

\n\n

Solution:

\n

Use the gorilla/csrf library or implement your own middleware:

\n
import "github.com/gorilla/csrf"\n\nfunc main() {\n    r := mux.NewRouter()\n    r.Use(csrf.Protect([]byte("32-byte-key")))\n    // ...\n}
\n\n

4. Insecure Error Handling

\n\n

A common mistake is returning system error messages to the user, which can reveal the internal structure of the application.

\n\n

Example of vulnerable code:

\n
if err != nil {\n    http.Error(w, err.Error(), http.StatusInternalServerError)\n}
\n\n

How to fix:

\n
if err != nil {\n    log.Printf("Error: %v", err)\n    http.Error(w, "Internal Server Error", http.StatusInternalServerError)\n}
\n\n

5. Information Leakage via Headers

\n\n

By default, a Go server may reveal the Go version, server type, and other service information.

\n\n

Solution:

\n
type 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\n

6. Incorrect Goroutine Handling

\n\n

Goroutines are a powerful Go tool, but their incorrect use can lead to race conditions and memory leaks.

\n\n

Example of vulnerable code:

\n
var counter int\nfor i := 0; i < 1000; i++ {\n    go func() {\n        counter++ // race condition!\n    }()\n}
\n\n

How to fix:

\n
var 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\n

7. Insecure Password Storage

\n\n

Storing passwords in plain text or using weak hashes (MD5, SHA1) is a serious mistake.<

Blogs

Book Recommendations