Header Injection in Cockroachdb
How Header Injection Manifests in Cockroachdb
Header injection in Cockroachdb typically occurs when HTTP headers are used as input for SQL operations or when Cockroachdb's built-in HTTP interface is exposed without proper validation. This vulnerability allows attackers to manipulate headers to execute unauthorized queries, bypass authentication, or extract sensitive data.
// Vulnerable pattern in Go applications using Cockroachdb
func handleRequest(w http.ResponseWriter, r *http.Request) {
tenantID := r.Header.Get("X-Tenant-ID")
// DANGEROUS: Header value directly interpolated into SQL
query := fmt.Sprintf("SELECT * FROM users WHERE tenant_id = '%s'", tenantID)
rows, _ := db.Query(query)
// Process results...
}In Cockroachdb, this becomes particularly dangerous because the database's distributed architecture means header injection can affect multiple nodes simultaneously. Attackers can exploit this by crafting headers that:
- Modify query logic through SQL injection in header values
- Trigger Cockroachdb's time travel queries using timestamp headers
- Access data across tenant boundaries in multi-tenant deployments
- Exploit Cockroachdb's JSONB handling when headers contain JSON data
Cockroachdb's support for PostgreSQL-compatible syntax means it's vulnerable to the same header injection patterns as PostgreSQL, but with additional risks due to its distributed nature. For example, the FOR SYSTEM TIME AS OF clause can be manipulated through headers:
// Vulnerable time travel query
func getHistoricalData(w http.ResponseWriter, r *http.Request) {
timestamp := r.Header.Get("X-Historical-Timestamp")
// Header directly used in time travel query
query := fmt.Sprintf(`
SELECT * FROM orders
FOR SYSTEM TIME AS OF '%s'
WHERE status = 'completed'
`, timestamp)
rows, _ := db.Query(query)
}Attackers can manipulate the X-Historical-Timestamp header to access data from arbitrary points in time, potentially exposing information they shouldn't have access to.
Cockroachdb-Specific Detection
Detecting header injection in Cockroachdb environments requires understanding both the HTTP layer and the database's specific behaviors. middleBrick's scanning approach for Cockroachdb includes:
| Detection Method | Cockroachdb-Specific Checks | Why It Matters |
|---|---|---|
| Header Analysis | SQL keyword detection in header values | Cockroachdb's SQL parser is more permissive than many databases |
| Time Travel Queries | FOR SYSTEM TIME clause analysis | Exploits Cockroachdb's unique temporal features |
| Tenant Isolation | Cross-tenant data access attempts | Cockroachdb's multi-tenant architecture requires strict isolation |
| JSONB Injection | JSON path injection testing | Cockroachdb's advanced JSONB support creates new attack surfaces |
middleBrick specifically tests for Cockroachdb's distributed query patterns by sending headers that attempt to:
- Trigger distributed transaction manipulation
- Exploit Cockroachdb's range-based sharding through header values
- Manipulate Cockroachdb's consistency level headers
- Test Cockroachdb's CDC (Change Data Capture) endpoints
For manual detection, examine your application code for patterns where HTTP headers are used in database operations:
# Check for header-to-SQL patterns in Go code
grep -r "Header\.Get" . | grep -E "(Query|Exec|Prepare)"Look specifically for headers that might interact with Cockroachdb's unique features:
// Dangerous pattern: Cockroachdb-specific headers
func handleDistributedQuery(w http.ResponseWriter, r *http.Request) {
consistency := r.Header.Get("X-Consistency-Level") // Can be 'stale', 'serializable', etc.
// Header directly affects Cockroachdb's consistency behavior
query := fmt.Sprintf(`
SELECT * FROM critical_data
WITH (consistency = '%s')
`, consistency)
rows, _ := db.Query(query)
}This pattern is dangerous because Cockroachdb's consistency levels can be manipulated to bypass security controls or access stale data that should be protected.
Cockroachdb-Specific Remediation
Remediating header injection in Cockroachdb requires a defense-in-depth approach that addresses both the HTTP layer and Cockroachdb's specific features. Here are Cockroachdb-specific fixes:
// SAFE: Parameterized queries with header input
func handleRequestSafe(w http.ResponseWriter, r *http.Request) {
tenantID := r.Header.Get("X-Tenant-ID")
// Use parameterized queries - Cockroachdb handles this safely
query := "SELECT * FROM users WHERE tenant_id = $1"
rows, err := db.Query(query, tenantID)
if err != nil {
http.Error(w, "Database error", 500)
return
}
// Process results...
}For Cockroachdb's time travel features, validate timestamp headers against a strict pattern:
import "time"func validateTimestamp(ts string) (time.Time, error) {
layout := "2006-01-02 15:04:05.000000-07:00"
// Parse with strict layout - rejects malformed timestamps
t, err := time.Parse(layout, ts)
if err != nil {
return time.Time{}, err
}
// Additional validation: check if timestamp is within allowed range
if t.After(time.Now()) {
return time.Time{}, errors.New("timestamp in future")
}
return t, nil
}
func getHistoricalDataSafe(w http.ResponseWriter, r *http.Request) {
timestamp := r.Header.Get("X-Historical-Timestamp")
t, err := validateTimestamp(timestamp)
if err != nil {
http.Error(w, "Invalid timestamp", 400)
return
}
// Safe parameterized query with Cockroachdb's time travel
query := "SELECT * FROM orders FOR SYSTEM TIME AS OF $1 WHERE status = 'completed'"
rows, err := db.Query(query, t)
// Process results...
}For multi-tenant Cockroachdb deployments, implement strict tenant isolation:
type TenantContext struct {
ID string
Role string
AllowedDBs []string
}
func withTenantContext(next http.Handler, tenantStore TenantStore) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
tenantID := r.Header.Get("X-Tenant-ID")
tenant, err := tenantStore.GetTenant(tenantID)
if err != nil {
http.Error(w, "Invalid tenant", 403)
return
}
// Store tenant context for use in Cockroachdb queries
ctx := context.WithValue(r.Context(), "tenant", tenant)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
// Safe Cockroachdb query with tenant isolation
func queryTenantData(w http.ResponseWriter, r *http.Request) {
tenant := r.Context().Value("tenant").(*TenantContext)
query := "SELECT * FROM data WHERE tenant_id = $1 AND allowed_db = ANY($2::text[])"
rows, err := db.Query(query, tenant.ID, pq.Array(tenant.AllowedDBs))
// Process results...
}middleBrick's CLI tool can help verify your remediation:
# Scan your API endpoints for header injection
middlebrick scan https://your-api.com --output json
# Check the report for Cockroachdb-specific findings
middlebrick report --format htmlThe GitHub Action integration allows you to fail builds if header injection vulnerabilities are detected:
name: API Security Scan
on: [push, pull_request]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run middleBrick Scan
run: |
npx middlebrick scan ${{ secrets.API_URL }} \
--output json \
--fail-on-severity high
continue-on-error: false