Noções Básicas de Segurança em Go
9 exemplos para você começar com Segurança - 7 básicos e 2 intermediários.
Busque em todas as páginas da documentação
9 exemplos para você começar com Segurança - 7 básicos e 2 intermediários.
mkdir seclab && cd seclab && go mod init example.com/seclab.openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes -subj "/CN=localhost".go install golang.org/x/vuln/cmd/govulncheck@latest.Defina MinVersion para que os clientes não possam negociar TLS 1.0 ou 1.1.
package main
import (
"crypto/tls"
"net/http"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("ok"))
})
srv := &http.Server{
Addr: ":8443",
Handler: mux,
TLSConfig: &tls.Config{
MinVersion: tls.VersionTLS12,
},
}
srv.ListenAndServeTLS("cert.pem", "key.pem")
}tls.Config no servidor se aplica a todos os handshakes TLS nessa conexão.Relacionado: Configuração de crypto/tls e Gerenciamento de Certificados - suítes de criptografia e mTLS
Nunca codifique chaves de API; carregue na inicialização e falhe se faltarem.
package main
import (
"fmt"
"os"
)
func mustEnv(key string) string {
v := os.Getenv(key)
if v == "" {
fmt.Fprintf(os.Stderr, "missing required env %s\n", key)
os.Exit(1)
}
return v
}
func main() {
dbURL := mustEnv("DATABASE_URL")
_ = dbURL
}.env commitados.Relacionado: Segurança para Serviços Go: Padrões e Lacunas - o que a biblioteca padrão não fornece
Bloqueie clientes que enviam cabeçalhos muito lentamente.
package main
import (
"net/http"
"time"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hi"))
})
srv := &http.Server{
Addr: ":8080",
Handler: mux,
ReadHeaderTimeout: 5 * time.Second,
}
srv.ListenAndServe()
}ReadHeaderTimeout é o timeout de servidor único mais importante para conexões públicas.ListenAndServe.ReadTimeout, WriteTimeout e IdleTimeout para cobertura completa do ciclo de vida.Relacionado: Rate Limiting, CORS e Cabeçalhos de Segurança - middleware de borda adicional
Rejeite payloads excessivamente grandes antes do trabalho de decodificação JSON.
package main
import (
"io"
"net/http"
)
func createItem(w http.ResponseWriter, r *http.Request) {
r.Body = http.MaxBytesReader(w, r.Body, 1<<20) // 1 MiB
defer r.Body.Close()
body, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, "payload too large", http.StatusRequestEntityTooLarge)
return
}
_ = body
w.WriteHeader(http.StatusCreated)
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("POST /items", createItem)
http.ListenAndServe(":8080", mux)
}MaxBytesReader retorna 413 quando o limite é excedido.Close o corpo para que as conexões keep-alive possam ser reutilizadas.Relacionado: Validação de Entrada e Tratamento Seguro de HTML/JSON - validação de esquema após verificações de tamanho
Compare chaves de API ou HMACs sem saída antecipada no primeiro byte diferente.
package main
import (
"crypto/subtle"
"fmt"
)
func main() {
provided := []byte("secret-token")
expected := []byte("secret-token")
if subtle.ConstantTimeCompare(provided, expected) == 1 {
fmt.Println("match")
}
}== simples em strings pode vazar informações de tempo através de comparação com saída curta.crypto/subtle.ConstantTimeCompare requer slices de comprimento igual; normalize o comprimento primeiro, se necessário.bcrypt ou argon2).Escapa automaticamente o conteúdo do usuário em respostas HTML.
package main
import (
"html/template"
"net/http"
)
func main() {
tmpl := template.Must(template.New("p").Parse(`<p>{{.}}</p>`))
http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
name := r.URL.Query().Get("name")
tmpl.Execute(w, name)
})
http.ListenAndServe(":8080", nil)
}html/template escapa <, >, &, aspas, prevenindo XSS refletido em contexto HTML.text/template não escapa - use apenas para saída não HTML.Content-Type: application/json e codifique com encoding/json.Relacionado: Validação de Entrada e Tratamento Seguro de HTML/JSON - regras de validação e codificação
Verifique seu grafo de módulos em busca de vulnerabilidades conhecidas.
cd seclab
govulncheck ./...Relacionado: Verificação de Dependências com govulncheck e SBOM - portões de CI e exportação de SBOM
Nunca use http.DefaultClient em handlers de servidor.
package main
import (
"context"
"io"
"net/http"
"time"
)
func fetch(ctx context.Context, url string) ([]byte, error) {
client := &http.Client{Timeout: 10 * time.Second}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return nil, err
}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
return io.ReadAll(resp.Body)
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
_, _ = fetch(ctx, "https://example.com")
}Client.Timeout limita toda a troca, incluindo TLS e leitura do corpo.NewRequestWithContext honra o cancelamento quando o chamador ou o servidor são desligados.Rejeite requisições sem um token Bearer válido antes que os handlers sejam executados.
package main
import (
"context"
"net/http"
"strings"
)
type ctxKey string
const userKey ctxKey = "user"
func auth(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h := r.Header.Get("Authorization")
if !strings.HasPrefix(h, "Bearer ") {
http.Error(w, "unauthorized", http.StatusUnauthorized)
return
}
token := strings.TrimPrefix(h, "Bearer ")
if token == "" {
http.Error(w, "unauthorized", http.StatusUnauthorized)
return
}
ctx := context.WithValue(r.Context(), userKey, token)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
func main() {
mux := http.NewServeMux()
mux.Handle("/api/", auth(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("ok"))
})))
http.ListenAndServe(":8080", mux)
}Relacionado: Padrões de Autenticação e Autorização - JWT, RBAC e OAuth2
Versões da Stack: Esta página foi escrita para Go 1.26.x (padrão Green Tea GC, go fix modernizers - verifique o patch na build), chi (última versão - verifique na build), gin (última versão - verifique na build), echo (última versão - verifique na build), google.golang.org/grpc (última versão - verifique na build), sigs.k8s.io/controller-runtime (última versão - verifique na build), kubebuilder (última versão - verifique na build), tinygo (última versão - verifique os alvos de placa na build), wazero (última versão - verifique na build) e golangci-lint (última versão - verifique na build).
Revisado por Chris St. John·Última atualização: 18 de jul. de 2026