Denial Of Service in Gin with Cockroachdb
Denial Of Service in Gin with Cockroachdb — how this specific combination creates or exposes the vulnerability
A Denial of Service (DoS) risk in a Gin application using CockroachDB emerges from tight coupling between HTTP request handling and database behavior. When a Gin handler performs synchronous, long-running, or unbounded queries against CockroachDB without context timeouts or resource limits, each incoming request may hold database connections and goroutines. Under load, this can exhaust connection pools, memory, or thread-local resources, causing request latency to increase and eventually making the service unresponsive.
With CockroachDB, certain query patterns can amplify DoS risks. For example, queries that lack proper indexes may result in full table scans; distributed joins across many nodes can increase latency; and contention on hot rows or ranges can cause transaction retries. If Gin endpoints issue these queries without cancellation support, a slow or stuck database operation can block the HTTP handler, preventing the server from accepting new requests. This is especially relevant when the API surface includes unbounded list endpoints or heavy aggregation without pagination, where a single malicious or poorly formed request can degrade performance for all users.
The 12 parallel security checks in middleBrick identify DoS-related findings under categories such as Input Validation and Rate Limiting. For instance, missing request validation can lead to resource-intensive queries, while absent rate limiting allows repeated abusive calls. Similarly, missing pagination or timeout controls can expose unbounded database workloads. By correlating OpenAPI specifications with runtime tests, middleBrick can detect endpoints that may trigger high-latency CockroachDB operations and flag them with severity and remediation guidance, helping teams understand how specific Gin routes and CockroachDB interactions contribute to the overall risk score.
Cockroachdb-Specific Remediation in Gin — concrete code fixes
To reduce DoS exposure when Gin routes interact with CockroachDB, apply timeouts, context propagation, pagination, and query validation. Use context.WithTimeout on each request and pass it to database operations so that long-running queries are canceled promptly. Define sensible query limits and enforce pagination for list endpoints. Validate input parameters before constructing SQL to avoid expensive or unbounded scans.
Below are concrete, realistic examples using the CockroachDB Go driver with Gin. These snippets illustrate safe patterns that mitigate DoS risks.
Example 1: Context timeouts and cancellation
import (
"context"
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/cockroachdb/cockroach-go/v2/crdb"
"github.com/jackc/pgx/v4/pgxpool"
)
func getUserHandler(pool *pgxpool.Pool) gin.HandlerFunc {
return func(c *gin.Context) {
// Use a request-scoped context with timeout to avoid hanging queries
ctx, cancel := context.WithTimeout(c.Request.Context(), 2*time.Second)
defer cancel()
var user struct {
ID int64 `json:"id"`
Name string `json:"name"`
}
err := crdb.ExecuteTx(ctx, pool, nil, func(tx *pgxpool.Tx) error {
return tx.QueryRow(ctx, "SELECT id, name FROM users WHERE id = $1", c.Param("id")).Scan(&user.ID, &user.Name)
})
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalError, gin.H{"error": "unable to fetch user"})
return
}
c.JSON(http.StatusOK, user)
}
}
Example 2: Pagination and bounded queries
import (
"context"
"net/http"
"strconv"
"time"
"github.com/gin-gonic/gin"
"github.com/cockroachdb/cockroach-go/v2/crdb"
"github.com/jackc/pgx/v4/pgxpool"
)
type ListRequest struct {
Limit int `form:"limit" binding:"required,min=1,max=100"`
Offset int `form:"offset" binding:"required,min=0"`
}
func listItemsHandler(pool *pgxpool.Pool) gin.HandlerFunc {
return func(c *gin.Context)
{
var req ListRequest
if err := c.ShouldBindQuery(&req); err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "invalid query parameters"})
return
}
ctx, cancel := context.WithTimeout(c.Request.Context(), 3*time.Second)
defer cancel()
rows, err := crdb.ExecuteTx(ctx, pool, nil, func(tx *pgxpool.Tx) (*pgx.Rows, error) {
return tx.Query(ctx, "SELECT id, title, created_at FROM items ORDER BY id LIMIT $1 OFFSET $2", req.Limit, req.Offset)
})
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalError, gin.H{"error": "unable to list items"})
return
}
defer rows.Close()
var items []map[string]interface{}
for rows.Next() {
var id int64
var title string
var createdAt time.Time
if err := rows.Scan(&id, &title, &createdAt); err != nil {
c.AbortWithStatusJSON(http.StatusInternalError, gin.H{"error": "unable to scan row"})
return
}
items = append(items, map[string]interface{}{"id": id, "title": title, "created_at": createdAt})
}
c.JSON(http.StatusOK, items)
}
}
Example 3: Safe parameterized queries to avoid expensive plans
import (
"context"
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/cockroachdb/cockroach-go/v2/crdb"
"github.com/jackc/pgx/v4/pgxpool"
)
func searchItemsHandler(pool *pgxpool.Pool) gin.HandlerFunc {
return func(c *gin.Context) {
query := c.Query("q")
if query == "" {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "q parameter is required"})
return
}
ctx, cancel := context.WithTimeout(c.Request.Context(), 3*time.Second)
defer cancel()
var count int
err := crdb.ExecuteTx(ctx, pool, nil, func(tx *pgxpool.Tx) error {
// Use parameterized queries to allow CockroachDB to reuse prepared plans
return tx.QueryRow(ctx, "SELECT COUNT(*) FROM items WHERE title ILIKE '%' || $1 || '%'", query).Scan(&count)
})
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalError, gin.H{"error": "search failed"})
return
}
c.JSON(http.StatusOK, gin.H{"count": count})
}
}
These patterns help ensure that Gin endpoints remain responsive even under database latency or contention, reducing the likelihood of DoS conditions.
Related CWEs: resourceConsumption
| CWE ID | Name | Severity |
|---|---|---|
| CWE-400 | Uncontrolled Resource Consumption | HIGH |
| CWE-770 | Allocation of Resources Without Limits | MEDIUM |
| CWE-799 | Improper Control of Interaction Frequency | MEDIUM |
| CWE-835 | Infinite Loop | HIGH |
| CWE-1050 | Excessive Platform Resource Consumption | MEDIUM |