Sql Injection in Gorilla Mux with Jwt Tokens
Sql Injection in Gorilla Mux with Jwt Tokens — how this specific combination creates or exposes the vulnerability
SQL injection in a Gorilla Mux application that uses JWT tokens occurs when user-controlled data from the request is concatenated into SQL queries without proper parameterization, even though authentication is mediated by JWTs. The presence of JWT tokens does not prevent SQL injection; it only indicates the caller is authenticated. If a token is accepted but the handler builds queries by string interpolation, the authentication boundary is bypassed from the perspective of the API because the token is trusted but the input is not.
In practice, this often maps to the Authentication and Input Validation checks in middleBrick’s scan. For example, an endpoint like /users/{userID} authenticated via JWT may still execute SELECT * FROM users WHERE id = '" + userID + "'. An attacker who possesses a valid JWT (stolen or obtained via account takeover) can still inject SQL through userID. Because the router does not enforce strict input validation, the malicious payload is passed to the database, leading to unauthorized data access or modification. MiddleBrick’s unauthenticated attack surface testing treats the endpoint as unauthenticated for injection tests, exposing how input handling—not token presence—drives the risk.
Specific OWASP API Top 10 categories relevant here include Broken Object Level Authorization (BOLA/IDOR) when combined with injection, and Input Validation weaknesses. A real-world pattern is using string concatenation with httprouter path parameters and query parameters without sanitization. For instance, a handler might read r.URL.Query().Get("search") and embed it directly into a LIKE clause. Even with JWT-based middleware verifying identity, the injection remains because the SQL layer receives untrusted data. MiddleBrick’s checks for Property Authorization and Input Validation highlight these gaps by correlating spec definitions with runtime behavior, showing where path parameters, headers, or cookies feed into SQL strings.
Consider a vulnerable pattern: a route registered with router.HandleFunc("/api/profile", getProfile).Methods("GET") and a JWT middleware that sets ctx claims. If getProfile extracts a query parameter like category and builds a query such as "SELECT * FROM profiles WHERE category = '" + category + "'", the JWT token does nothing to neutralize the injection. The router ensures a token is present, but the SQL is still formed by concatenation. This is where middleBrick’s cross-referencing of OpenAPI specs and runtime findings can identify mismatches between declared authentication and actual input handling.
Real attack patterns include classic techniques like ' OR 1=1 -- to bypass filters, or stacked queries if the driver permits. Injection can also lead to exposure of sensitive data, aligning with Data Exposure findings in scans. Because JWT tokens are often issued with broad scopes, the blast radius of a successful injection is larger. MiddleBrick’s LLM/AI Security checks do not apply here, but the scanner’s Authentication and Input Validation components will flag the lack of parameterized queries and insufficient authorization checks at the property level.
Jwt Tokens-Specific Remediation in Gorilla Mux — concrete code fixes
Remediation centers on strict input validation and parameterized SQL, independent of JWT handling. JWT middleware should remain focused on identity verification, while data access layers must treat all user-supplied values as untrusted. The following examples show correct patterns for Gorilla Mux with JWT tokens.
Example 1: Safe query with path parameter and JWT middleware
package main
import (
"database/sql"
"net/http"
"github.com/gorilla/mux"
_ "github.com/lib/pq"
)
func getProfile(db *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
userID := vars["userID"]
// Use parameterized query; do not concatenate userID
row := db.QueryRow("SELECT id, email, name FROM users WHERE id = $1", userID)
var id int
var email, name string
if err := row.Scan(&id, &email, &name); err != nil {
http.Error(w, "not found", http.StatusNotFound)
return
}
w.Write([]byte(email))
}
}
func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
tokenString := r.Header.Get("Authorization")
// Verify JWT token and set claims in context
claims, err := verifyToken(tokenString)
if err != nil {
http.Error(w, "unauthorized", http.StatusUnauthorized)
return
}
ctx := context.WithValue(r.Context(), "claims", claims)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
func main() {
db, _ := sql.Open("postgres", "connstr")
r := mux.NewRouter()
r.HandleFunc("/api/profile/{userID}", getProfile(db)).Methods("GET")
r.Use(authMiddleware)
http.ListenAndServe(":8080", r)
}
Example 2: Safe query with query parameters and prepared statements
func searchProfiles(db *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
category := r.URL.Query().Get("category")
// Validate category against an allowlist or regex
if category == "" || !isValidCategory(category) {
http.Error(w, "bad request", http.StatusBadRequest)
return
}
stmt, err := db.Prepare("SELECT id, name FROM profiles WHERE category = $1")
if err != nil {
http.Error(w, "server error", http.StatusInternalServerError)
return
}
defer stmt.Close()
rows, err := stmt.Query(category)
if err != nil {
http.Error(w, "server error", http.StatusInternalServerError)
return
}
defer rows.Close()
for rows.Next() {
var id int
var name string
rows.Scan(&id, &name)
w.Write([]byte(name + ","))
}
}
}
func isValidCategory(cat string) bool {
// Example allowlist
allowed := map[string]bool{"tech": true, "health": true, "finance": true}
return allowed[cat]
}
Key practices: always use $1, $2 placeholders (PostgreSQL) or ? (other drivers) with db.Query or db.Exec; avoid fmt.Sprintf or string concatenation for SQL; validate path and query parameters against allowlists or strict regex; keep JWT verification separate from data access logic; ensure that claims from the token are not used to dynamically build SQL without validation. MiddleBrick’s scans can verify these patterns by checking that endpoints with authentication also enforce input validation and parameterized queries.
Related CWEs: inputValidation
| CWE ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |