HIGH crlf injectionchicockroachdb

Crlf Injection in Chi with Cockroachdb

Crlf Injection in Chi with Cockroachdb — how this specific combination creates or exposes the vulnerability

Crlf Injection occurs when an attacker can inject carriage return (CR, \r) and line feed (\n) characters into an HTTP response header, causing the header to be split and additional headers or body content to be injected. In a Go application using the Chi router, this typically arises when user-controlled input is reflected into headers such as Location, X-Forwarded-For, or custom headers without proper sanitization. When the application also interacts with Cockroachdb, a distributed SQL database, the injected header content can affect logging, redirection, or session handling that references database identifiers or URLs.

For example, consider a handler that takes a user-supplied returnUrl parameter and sets it in a Location header before redirecting. If the input contains \r\n sequences, an attacker can inject a new header such as Set-Cookie or manipulate the response body after the injected split. Even though Cockroachdb itself does not introduce the injection, an attacker might attempt to exfiltrate or manipulate data by poisoning a redirect that later includes a database primary key or tenant identifier stored in a header or cookie. In a microservice architecture where Chi routes requests to services that query Cockroachdb, an injected header can bypass intended routing or logging logic, potentially exposing sensitive query patterns or configuration details that aid further attacks.

The interaction with Cockroachdb becomes relevant when headers influence how application code builds database queries or connections. For instance, if a header value derived from user input is used to select a database or schema (which is strongly discouraged), CRLF injection could enable header smuggling to an upstream service that then executes unintended SQL against Cockroachdb. While Chi does not parse headers beyond standard Go http.Header handling, the framework’s flexibility with middleware makes it easy to inadvertently pass unsanitized values into downstream handlers that interact with the database. Therefore, the vulnerability is a result of improper input validation on headers in Chi, combined with application logic that references Cockroachdb identifiers or URLs in a way that can be influenced by injected header content.

Cockroachdb-Specific Remediation in Chi — concrete code fixes

Remediation focuses on strict validation and sanitization of user input before it is used in HTTP headers, and avoiding any direct use of external input in database interaction logic. Below are concrete code examples for a Chi router that safely handles user input and interacts with Cockroachdb using the pgx driver.

1. Sanitize header values and avoid reflection of raw user input

Never set headers directly from user input. If a redirect URL is required, validate and normalize it, and ensure it does not contain newline characters. Use a whitelist approach for domains or paths when possible.

import (
	"net/http"
	"strings"

	"github.com/labstack/chi/v5"
)

func safeRedirectHandler(db *sql.DB) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		userURL := r.URL.Query().Get("url")
		// Reject if contains CR or LF
		if strings.ContainsAny(userURL, "\r\n") {
			http.Error(w, "invalid parameter", http.StatusBadRequest)
			return
		}
		// Validate URL format and restrict to same host or approved domains
		// ... validation logic ...
		http.Redirect(w, r, userURL, http.StatusFound)
	}
}

2. Use parameterized queries with Cockroachdb to avoid SQL injection and keep data handling separate from headers

When interacting with Cockroachdb, always use prepared statements or parameterized queries. Do not concatenate headers or request metadata into SQL strings.

import (
	"database/sql"
	"log"

	_ "github.com/jackc/pgx/v5/stdlib"
)

func getTenantData(w http.ResponseWriter, r *http.Request) {
	tenantID := chi.URLParam(r, "tenantID")
	var orgName string
	// Use parameterized query to prevent SQL injection
	row := db.QueryRow(r.Context(), "SELECT org_name FROM tenants WHERE id = $1", tenantID)
	if err := row.Scan(&orgName); err != nil {
		if err == sql.ErrNoRows {
			http.Error(w, "not found", http.StatusNotFound)
			return
		}
		log.Printf("db query error: %v", err)
		http.Error(w, "internal error", http.StatusInternalServerError)
		return
	}
	w.Write([]byte(orgName))
}

3. Apply middleware to reject malicious headers early

Use Chi middleware to inspect and drop headers containing newline characters before they reach business logic that might reference Cockroachdb connection parameters or dynamic header-based routing.

func headerSanityMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		for name, values := range r.Header {
			for _, v := range values {
				if strings.ContainsAny(v, "\r\n") {
					http.Error(w, "malformed header", http.StatusBadRequest)
					return
				}
			}
		}
		next.ServeHTTP(w, r)
	})
}

func main() {
	r := chi.NewRouter()
	r.Use(headerSanityMiddleware)
	r.Get("/data/{tenantID}", getTenantData)
	http.ListenAndServe(":8080", r)
}

4. Avoid using headers to influence Cockroachdb connections or queries

Do not derive database connection strings, schema names, or query parameters from HTTP headers that can be influenced by an attacker. If multi-tenancy is required, map tenant identifiers through authenticated session state or URL parameters that are validated against a trusted source, not from raw headers.

// Anti-pattern: using header to select database (do not do this)
func badDBSelection(w http.ResponseWriter, r *http.Request) {
	schema := r.Header.Get("X-Tenant-Schema")
	// This is unsafe; CRLF injection could manipulate the header to point to another schema or inject SQL-like content
	connStr := "postgresql://user:pass@cockroachdb:26257/" + schema
	db, err := sql.Open("pgx", connStr)
	if err != nil {
		http.Error(w, "failed to connect", http.StatusInternalServerError)
		return
	}
	defer db.Close()
}

Frequently Asked Questions

Can CRLF injection in Chi affect Cockroachdb queries even if input is not directly passed to SQL?
Yes. While Cockroachdb queries are typically parameterized, CRLF injection in Chi can manipulate HTTP headers that influence routing, logging, or middleware behavior. This may lead to unintended selection of database connections, schema names, or exposure of identifiers that an attacker can leverage for further attacks.
Does using middlewareSanityMiddleware fully prevent CRLF injection in a Chi application with Cockroachdb?
Middleware that rejects headers containing carriage return or line feed characters significantly reduces risk, but you must also validate and sanitize all user input used in redirects, cookies, and any downstream logic that may reference Cockroachdb identifiers. Defense in depth includes input validation, parameterized queries, and avoiding reflection of raw input into headers.