Xml External Entities in Gorilla Mux with Cockroachdb
Xml External Entities in Gorilla Mux with Cockroachdb — how this specific combination creates or exposes the vulnerability
An XML External Entity (XXE) attack leverages insecure XML processing to expose local files, trigger SSRF, or cause denial of service. When a Go service built with Gorilla Mux parses XML payloads without disabling external entity resolution, and the application interacts with Cockroachdb, the combination can expose database-relative behaviors and information leaks even if Cockroachdb itself is not directly exploited via XML.
Gorilla Mux is a URL router and dispatcher; it does not parse XML. The vulnerability arises when an HTTP handler registered with Mux uses an XML decoder that does not restrict entity expansion. For example, a handler that accepts incoming XML metadata and forwards it to Cockroachdb via a query or a row mapping can inadvertently process malicious external entities. If the XML parser resolves entities against local files or internal services, an attacker can read files relevant to Cockroachdb configuration or connection logic, such as certificates or startup scripts, especially when file paths or error messages reference Cockroachdb-specific directories or schemas.
Cockroachdb does not process XML, so the database is not directly attacked via XML injection. However, XXE can lead to Server-Side Request Forgery (SSRF) against internal endpoints that interact with Cockroachdb, such as a local admin UI or a service that proxies SQL requests. In a microservice environment where Gorilla Mux routes requests to a Cockroachdb-backed service, an SSRF induced by XXE could allow an attacker to probe internal SQL ports or configuration endpoints that are not exposed externally. Additionally, error messages returned by Cockroachdb might be influenced by crafted XML inputs if the application embeds XML-derived data into SQL queries or logs, leading to indirect data exposure or log injection.
Consider a handler that unmarshals an XML payload into a struct and then builds a SQL string for Cockroachdb:
type Metadata struct {
Table string `xml:"table"`
Key string `xml:"key"`
}
func handler(w http.ResponseWriter, r *http.Request) {
var meta Metadata
decoder := xml.NewDecoder(r.Body)
if err := decoder.Decode(&meta); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
query := fmt.Sprintf("SELECT * FROM %s WHERE key = '%s'", meta.Table, meta.Key)
rows, err := db.Query(query)
// handle rows and errors, possibly logging or formatting errors that include request-origin data
}
If the XML decoder resolves entities, an attacker can supply a payload that reads /etc/cockroachdb/certs or other configuration files and includes their content in the Table or Key fields, which then appear in logs or error responses. Even without direct file disclosure, the crafted XML can trigger SSRF to internal admin routes registered under the same Mux patterns, probing Cockroachdb readiness or status endpoints.
Because middleBrick tests unauthenticated attack surfaces and includes checks for SSRF and input validation, it can detect endpoints that accept XML with external entity references. The scanner does not rely on internal architecture, but it can identify whether XML parsing is configured safely and whether endpoints that interact with Cockroachdb are susceptible to injection or SSRF via malicious XML constructs.
Cockroachdb-Specific Remediation in Gorilla Mux — concrete code fixes
Remediation focuses on preventing XML entity expansion and avoiding unsafe construction of SQL statements when using Gorilla Mux. The following patterns assume you use the standard library encoding/xml and a Cockroachdb connection via database/sql with a lib/pq or pgx driver.
1. Disable external entity resolution
Wrap the XML decoder with a custom xml.Decoder that disables DTD and external entity resolution. Since the standard library does not provide a direct switch, you can use xml.NewDecoder with an io.LimitReader and a custom entity resolver that returns an error for external entities.
func safeXMLDecoder(r io.Reader) *xml.Decoder {
// Optional: limit size to prevent DoS
lr := &io.LimitedReader{R: r, N: 10 << 20} // 10 MB
decoder := xml.NewDecoder(lr)
decoder.Entity = xml.HTMLEntity // minimal built-in entities only
return decoder
}
Use it in your handler:
func handler(w http.ResponseWriter, r *http.Request) {
decoder := safeXMLDecoder(r.Body)
var meta Metadata
if err := decoder.Decode(&meta); err != nil {
http.Error(w, "invalid payload", http.StatusBadRequest)
return
}
// proceed with validated meta
}
2. Use parameterized queries instead of string formatting
Never interpolate XML-derived values directly into SQL strings. Use placeholders to ensure values are properly escaped and types are handled safely. For Cockroachdb, the driver supports $1, $2 placeholders.
func handler(w http.ResponseWriter, r *http.Request) {
var meta Metadata
decoder := xml.NewDecoder(r.Body)
// Consider additional validation for meta.Table, e.g., allowlist
if err := decoder.Decode(&meta); err != nil {
http.Error(w, "invalid payload", http.StatusBadRequest)
return
}
// Validate table name against an allowlist
allowed := map[string]bool{"widgets": true, "logs": true}
if !allowed[meta.Table] {
http.Error(w, "invalid table", http.StatusBadRequest)
return
}
query := "SELECT * FROM " + meta.Table + " WHERE key = $1"
row := db.QueryRow(query, meta.Key)
var value string
if err := row.Scan(&value); err != nil {
http.Error(w, "query failed", http.StatusInternalServerError)
return
}
fmt.Fprintf(w, "value: %s", value)
}
3. Validate and restrict input sources
Apply strict allowlists for XML element values that map to SQL identifiers. For paths or configuration references, avoid using raw XML content to construct filesystem paths that could expose Cockroachdb-related files. If you must read configuration, load it at startup from a secure, predefined location rather than from user-supplied XML.
4. Secure error handling
Ensure error messages do not leak stack traces or internal paths that could hint at Cockroachdb installation locations. Use generic error responses in production and log detailed errors server-side with appropriate access controls.
5. Middleware and routing hygiene
Since Gorilla Mux is a router, ensure that endpoints accepting XML are clearly separated from endpoints that perform Cockroachdb operations. Apply strict content-type checks and avoid falling back to XML parsing on routes that do not expect XML.
These steps mitigate XXE and related injection risks while preserving the ability to interact safely with Cockroachdb through Go handlers registered with Gorilla Mux.