Missing Tls in Gorilla Mux with Jwt Tokens
Missing Tls in Gorilla Mux with Jwt Tokens — how this specific combination creates or exposes the vulnerability
Serving JWT-based authentication over unencrypted HTTP with Gorilla Mux exposes tokens in transit, enabling interception and token replay. When endpoints protected by JWT are reachable without TLS, an attacker on the network path can capture Authorization headers containing signed tokens. Because the token itself is valid, the API treats the request as authenticated, undermining the authentication boundary that JWT is meant to enforce.
This combination—Gorilla Mux routing and JWT middleware—commonly appears in services that terminate TLS at a load balancer or proxy but fail to enforce it at the application layer. If middleware validates the token but transport security is missing, tokens can be stolen via session hijacking, man-in-the-middle attacks on local networks, or insecure internal routing. The scanner checks for missing TLS by verifying that endpoints providing JWT-protected resources are served over HTTPS, inspecting responses and headers for redirects or HSTS indicators.
During a scan, middleBrick tests unauthenticated attack surface and flags endpoints that expose JWT-related routes without redirecting to HTTPS or enforcing secure transport. Findings include missing HTTP Strict Transport Security (HSTS), lack of secure cookie attributes if tokens are stored in cookies, and absence of server-side redirect from HTTP to HTTPS. These gaps are especially critical for endpoints issuing or validating JWTs, because captured tokens can be reused until expiration, enabling unauthorized access across sessions.
Jwt Tokens-Specific Remediation in Gorilla Mux — concrete code fixes
Remediation centers on enforcing HTTPS for all routes and ensuring JWT validation occurs only over secure channels. Use Gorilla Mux with a TLS-enabled server and add middleware that redirects HTTP to HTTPS before JWT verification runs. Below is a complete, working example that demonstrates secure setup with JWT validation, HSTS, and secure cookie handling for token transport.
package main
import (
"crypto/tls"
"fmt"
"net/http"
"strings"
"github.com/gorilla/mux"
)
// JWTMiddleware validates Authorization header "Bearer <token>".
func JWTMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
auth := r.Header.Get("Authorization")
if auth == "" {
http.Error(w, `{"error":"authorization header required`}", http.StatusUnauthorized)
return
}
const bearerPrefix = "Bearer "
if !strings.HasPrefix(auth, bearerPrefix) {
http.Error(w, `{"error":"invalid authorization header format`}", http.StatusUnauthorized)
return
}
token := strings.TrimPrefix(auth, bearerPrefix)
// Replace with your actual token validation logic (e.g., jwt.Parse).
if token == "insecure_example_invalid" {
http.Error(w, `{"error":"invalid token`}", http.StatusUnauthorized)
return
}
// Token is valid; proceed.
next.ServeHTTP(w, r)
})
}
// secureHeaders sets HSTS and secure cookie flags when tokens are stored in cookies.
func secureHeaders(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains")
// Example if you set JWT in a cookie:
// http.SetCookie(w, &http.Cookie{
// Name: "token",
// Value: token,
// Secure: true,
// HttpOnly: true,
// SameSite: http.SameSiteStrictMode,
// })
next.ServeHTTP(w, r)
})
}
// healthHandler for liveness/readiness.
func healthHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
fmt.Fprint(w, `{"status":"ok"}`)
}
func main() {
r := mux.NewRouter()
r.Use(secureHeaders)
// Public endpoint: no JWT required.
r.HandleFunc("/health", healthHandler).Methods("GET")
// Protected routes require JWT and must be served over HTTPS.
api := r.PathPrefix("/api").Subrouter()
api.Use(JWTMiddleware)
api.HandleFunc("/data", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
fmt.Fprint(w, `{"data":"secure response"}`)
}).Methods("GET")
srv := &http.Server{
Addr: ":8443",
Handler: r,
TLSConfig: &tls.Config{
MinVersion: tls.VersionTLS12,
},
}
// In production, use ListenAndServeTLS with valid cert and key paths.
// For local testing without TLS, HTTPS enforcement is bypassed, but scans will flag this.
// Example with cert files:
// err := srv.ListenAndServeTLS("server.crt", "server.key")
// For demonstration, we start HTTP to illustrate the redirect pattern.
go func() {
fmt.Println("HTTP server on :8080 (redirects to HTTPS)")
// Example redirect handler:
http.ListenAndServe(":8080", redirectToHTTPS(srv))
}()
fmt.Println("HTTPS server on :8443")
if err := srv.ListenAndServeTLS("server.crt", "server.key"); err != nil {
panic(err)
}
}
// redirectToHTTPS returns a handler that redirects all requests to HTTPS.
func redirectToHTTPS(hs *http.Server) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "https://"+strings.TrimPrefix(r.Host, ":80")+r.URL.String(), http.StatusPermanentRedirect)
})
}
Key remediation points:
- Enforce HTTPS for all routes, especially those validating or issuing JWTs.
- Add HSTS headers to instruct browsers to always use HTTPS.
- Set Secure and HttpOnly flags on cookies if storing JWTs client-side.
- Use strong minimum TLS settings (TLS 1.2+).
- Configure Gorilla Mux with a tls.Config specifying minimum versions and cipher suites.
By combining transport security with JWT validation, you ensure tokens cannot be intercepted and reused, reducing the risk of token theft and unauthorized access.
Related CWEs: encryption
| CWE ID | Name | Severity |
|---|---|---|
| CWE-319 | Cleartext Transmission of Sensitive Information | HIGH |
| CWE-295 | Improper Certificate Validation | HIGH |
| CWE-326 | Inadequate Encryption Strength | HIGH |
| CWE-327 | Use of a Broken or Risky Cryptographic Algorithm | HIGH |
| CWE-328 | Use of Weak Hash | HIGH |
| CWE-330 | Use of Insufficiently Random Values | HIGH |
| CWE-338 | Use of Cryptographically Weak PRNG | MEDIUM |
| CWE-693 | Protection Mechanism Failure | MEDIUM |
| CWE-757 | Selection of Less-Secure Algorithm During Negotiation | HIGH |
| CWE-261 | Weak Encoding for Password | HIGH |