Go Security

Go

Go has strong security defaults but still has common vulnerability patterns. Focus areas include SQL injection, command injection, and SSRF.

SQL Injection in Go

go-sqli.go
go
// VULNERABLE - String formatting
query := fmt.Sprintf("SELECT * FROM users WHERE id = %s", userID)
rows, err := db.Query(query)

// SECURE - Parameterized queries
rows, err := db.Query("SELECT * FROM users WHERE id = ?", userID)

// SECURE - With GORM
db.Where("id = ?", userID).First(&user)

// VULNERABLE - GORM raw SQL
db.Raw(fmt.Sprintf("SELECT * FROM users WHERE name = '%s'", name)).Scan(&users)

Command Injection

go-security.go
go
// VULNERABLE - exec.Command with shell
cmd := exec.Command("sh", "-c", "ls " + userInput)

// SECURE - Direct command without shell
cmd := exec.Command("ls", userInput)

// Path traversal check
func safePath(base, userPath string) (string, error) {
    cleaned := filepath.Clean(userPath)
    full := filepath.Join(base, cleaned)
    
    // Ensure path stays within base directory
    if !strings.HasPrefix(full, filepath.Clean(base)+string(os.PathSeparator)) {
        return "", errors.New("path traversal detected")
    }
    return full, nil
}

// SSRF prevention
// Always validate URLs before making requests
func validateURL(input string) error {
    u, err := url.Parse(input)
    if err != nil {
        return err
    }
    // Block internal IPs
    if u.Hostname() == "localhost" || u.Hostname() == "127.0.0.1" {
        return errors.New("internal hosts not allowed")
    }
    return nil
}