Integer Overflow in Gin with Cockroachdb
Integer Overflow in Gin with Cockroachdb — how this specific combination creates or exposes the vulnerability
An integer overflow in a Gin application that interacts with CockroachDB can occur when user-supplied numeric input is used to compute sizes, offsets, or limits for SQL operations without proper validation. In Go, integers have fixed bit widths; for example, an int is architecture-dependent (32 or 64 bits), while int64 is always 64 bits. If an attacker provides a large value that, when added to or multiplied by another value, exceeds the maximum representable value (e.g., math.MaxInt64 for int64), the value wraps around to a negative or small positive number. This can cause logic errors such as allocating a tiny buffer, setting a negative LIMIT in SQL, or producing an incorrect WHERE clause.
When this overflowed value is passed to CockroachDB, the resulting SQL may behave unexpectedly. CockroachDB adheres to PostgreSQL wire protocol and semantics, and it will typically return an error for invalid input (e.g., negative LIMIT), but in some cases, the overflowed integer may produce a valid-looking but malicious query. For instance, an overflowed offset can cause the query to read unintended rows, potentially bypassing pagination controls. In the context of BOLA/IDOR, an attacker might manipulate an integer parameter that indexes into a dataset; after overflow, the index wraps and grants access to another user’s data.
Because middleBrick scans unauthenticated attack surfaces and includes checks for Input Validation and BOLA/IDOR, it can surface these logic flaws. The scanner does not rely on internal architecture, but it tests how the API behaves when supplied with large or unexpected numeric values. A vulnerable Gin endpoint might accept a query parameter like ?offset=9223372036854775807, which overflows when incremented, leading to a negative offset that CockroachDB interprets differently than intended. The scan’s runtime tests map these behaviors to the 12 security checks, highlighting how unchecked integer operations can undermine data isolation and integrity even when the database layer is robust.
Cockroachdb-Specific Remediation in Gin — concrete code fixes
Remediation focuses on validating and sanitizing all integer inputs before using them in SQL statements sent to CockroachDB. Use types with well-defined sizes (e.g., int64) and check bounds before arithmetic. For pagination, prefer cursor-based approaches with opaque tokens rather than integer offsets when possible. When you must use offsets, validate that the value is non-negative and within acceptable limits before passing it to the query.
Example: Safe pagination with validation
import (
"context"
"errors"
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"github.com/lib/pq"
)
func getItems(c *gin.Context) {
const maxLimit = 100
ctx := c.Request.Context()
limitStr := c.DefaultQuery("limit", "20")
offsetStr := c.DefaultQuery("offset", "0")
limit, err := strconv.Atoi(limitStr)
if err != nil || limit < 1 || limit > maxLimit {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid limit"})
return
}
offset, err := strconv.Atoi(offsetStr)
if err != nil || offset < 0 {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid offset"})
return
}
var items []string
// Use parameterized queries to CockroachDB to avoid SQL injection
err = db.Select(&items, "SELECT name FROM items ORDER BY id LIMIT $1 OFFSET $2", limit, offset)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "database error"})
return
}
c.JSON(http.StatusOK, items)
}
Example: Detecting overflow before arithmetic
func safeAdd(a, b int64) (int64, error) {
if b > 0 && a > math.MaxInt64 - b {
return 0, errors.New("integer overflow")
}
if b < 0 && a < math.MinInt64 - b {
return 0, errors.New("integer underflow")
}
return a + b, nil
}
Example: Using uint64 for IDs and checking bounds
func getUser(c *gin.Context) {
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
return
}
if id == 0 {
c.JSON(http.StatusBadRequest, gin.H{"error": "id must be positive"})
return
}
var user User
err = db.Get(&user, "SELECT id, name, email FROM users WHERE id = $1", id)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "database error"})
return
}
c.JSON(http.StatusOK, user)
}
These examples assume a PostgreSQL-compatible database like CockroachDB. The driver (e.g., pq or cockroachdb/sql.drive) handles parameter substitution safely, but the application must ensure that integers used in LIMIT, OFFSET, and arithmetic are within expected ranges. middleBrick’s scans can validate that such checks are present by testing endpoints with boundary values and observing whether the API rejects invalid integers or behaves unexpectedly.