Sql Injection in Gorilla Mux with Basic Auth
Sql Injection in Gorilla Mux with Basic Auth — how this specific combination creates or exposes the vulnerability
SQL injection in a Gorilla Mux service that uses HTTP Basic Authentication arises from a combination of routing, handler implementation, and credential handling. When credentials are decoded from the Authorization header in each request, they are often parsed and used to build database queries. If any part of the request path, query parameters, or header values is concatenated into SQL strings without proper parameterization, an attacker can manipulate input to alter query logic.
Gorilla Mux does not sanitize inputs; it only provides route variables and query parameters. Basic Auth adds a step where the server decodes user:password, and this decoded data might be forwarded into SQL statements. For example, extracting the username for a lookup and embedding it directly into a query creates a classic SQL injection vector. Attackers can send crafted URLs like /users/'; DROP TABLE users; -- or inject payloads via query parameters, relying on the router to pass them to handlers. Without parameterized queries or strict input validation, these payloads can execute unintended commands. This risk is especially pronounced when handlers use credentials to select or update records in a database, effectively coupling authentication state with data access patterns that are vulnerable to injection.
Real-world attack patterns mirror concerns in the OWASP API Top 10 and relate to common CVEs found in libraries that interact with SQL databases. Even though the scanner does not test authenticated states, the unauthenticated attack surface tested by middleBrick can still identify endpoints where user-controlled input reaches SQL generation. The presence of Basic Auth does not inherently mitigate or introduce SQL injection; it is how the extracted credentials and request data are used in queries that determines risk. For instance, using the decoded username in a raw SQL string such as SELECT * FROM users WHERE username = ' + usernameVar + ' is unsafe. Proper remediation requires strict separation of data and commands, regardless of the authentication mechanism.
Basic Auth-Specific Remediation in Gorilla Mux — concrete code fixes
To secure a Gorilla Mux service using Basic Authentication, always treat credentials and user input as untrusted. Use parameterized queries or prepared statements for all database operations, and avoid interpolating any request-derived data into SQL strings. Below are concrete code examples demonstrating secure practices.
First, a safe handler that extracts Basic Auth credentials and uses parameterized queries with database/sql:
package main
import (
"database/sql"
"encoding/base64"
"fmt"
"net/http"
"strings"
"github.com/gorilla/mux"
_ "github.com/lib/pq"
)
db *sql.DB // assume initialized elsewhere
func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
auth := r.Header.Get("Authorization")
if auth == "" || !strings.HasPrefix(auth, "Basic ") {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
payload, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(auth, "Basic "))
if err != nil {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
// validate credentials against a secure source, do not use raw credentials in SQL
parts := strings.SplitN(string(payload), ":", 2)
if len(parts) != 2 {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
// Example: verify credentials via a parameterized query
var valid bool
err = db.QueryRow("SELECT active FROM users WHERE username = $1 AND password_hash = crypt($2, password_hash)", parts[0], parts[1]).Scan(&valid)
if err != nil || !valid {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
// Credentials valid, proceed
ctx := context.WithValue(r.Context(), "username", parts[0])
next.ServeHTTP(w, r.WithContext(ctx))
})
}
func userInfoHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
// Never directly use vars["username"] in SQL; use parameterized queries
var name string
err := db.QueryRow("SELECT full_name FROM profiles WHERE username = $1", vars["username"]).Scan(&name)
if err != nil {
http.Error(w, "Not found", http.StatusNotFound)
return
n }
fmt.Fprintf(w, "Name: %s", name)
}
func main() {
r := mux.NewRouter()
r.Use(authMiddleware)
r.HandleFunc("/users/{username}", userInfoHandler).Methods("GET")
http.ListenAndServe(":8080", r)
}
Key points in this example:
- Basic Auth credentials are decoded and validated using a parameterized query with
$1placeholders, preventing SQL injection in authentication itself. - Route variables (e.g.,
{username}) are passed as parameters to subsequent queries rather than interpolated into SQL strings. - Sensitive operations like password checking use
cryptin SQL (where supported) rather than handling plaintext passwords directly in application logic.
Additionally, enforce strict input validation on path and query parameters before using them in any database interaction. Even with Basic Auth, treat all incoming data as potentially malicious. middleBrick can help identify endpoints where unvalidated inputs may lead to injection by scanning the unauthenticated attack surface; findings will include guidance on using parameterized queries and input sanitization.
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 |