Integer Overflow in Cockroachdb
How Integer Overflow Manifests in CockroachDB
CockroachDB stores integer values using the PostgreSQL‑compatible INT, BIGINT, and SMALLINT types. When an application performs arithmetic that exceeds the range of the target type, CockroachDB will reject the statement with an error such as "integer out of range". However, the vulnerability often appears earlier in the application layer, where the overflow occurs before the value is sent to the database. Typical attack patterns include:
- Sequence exhaustion via crafted IDs: An API that generates identifiers by incrementing a BIGINT column (e.g.,
id BIGSERIAL PRIMARY KEY) may accept a user‑suppliedoffsetparameter. If the offset is a large negative number, the resulting sequence value can wrap or cause the next generated ID to exceed the BIGINT limit, leading to an error that can be leveraged for denial‑of‑service or to expose error messages. - Financial‑logic overflow: A service that calculates balances using
INT8columns may add a user‑controlled amount without checking for overflow. For example,new_balance = current_balance + amountwhereamountis near9223372036854775807. The intermediate sum overflows the application’sint64variable, producing a low or negative value that is then written to CockroachDB, corrupting accounting data. - Batch‑size manipulation: Endpoints that accept a
limitorbatch_sizeparameter to control how many rows are fetched or inserted may compute offsets asoffset = page * limit. Supplying a hugelimitcan cause the multiplication to overflow, resulting in a small or negative offset that leads to unexpected pagination, data leakage, or excessive resource consumption.
These patterns are not unique to CockroachDB, but because CockroachDB follows PostgreSQL’s strict integer‑overflow semantics, any overflow that reaches the database will cause an immediate error, making the issue easier to detect via monitoring or automated scanning.
CockroachDB‑Specific Detection
Detecting integer‑overflow risk in APIs that talk to CockroachDB can be done with static analysis of the service code, but a black‑box scanner like middleBrick can uncover the issue by probing unauthenticated endpoints for suspicious behavior. middleBrick’s 12 parallel checks include Input Validation and Property Authorization, which together can trigger overflow conditions:
- Input Validation checks: middleBrick sends deliberately crafted numeric payloads (e.g., values near the limits of INT, BIGINT, SMALLINT) to parameters that are later used in arithmetic or as identifiers. If the endpoint returns a 500 error with a message containing "integer out of range" or similar, the scanner flags a potential overflow.
- Property Authorization checks: By attempting to write values that exceed column definitions (e.g., inserting
9223372036854775808into a BIGINT column), middleBrick verifies whether the API enforces proper server‑side validation. Lack of validation results in a database error that is surfaced in the response.
Example of a middleBrick CLI command that would trigger such a detection:
middlebrick scan https://api.example.com/transactions \
--header "Content-Type: application/json" \
--data '{"amount": 9223372036854775807, "account_id": 1}'
If the service adds a fee or performs amount + fee without checking limits, CockroachDB will reject the insert and middleBrick will report an Input Validation finding with severity high.
Additionally, middleBrick can scan any exposed OpenAPI/Swagger specification. If the spec defines a parameter as type: integer without a maximum or minimum, the scanner notes the missing bounds as a property‑authorization gap that could lead to overflow.
CockroachDB‑Specific Remediation
The fix must happen in the application before data reaches CockroachDB, but you can also leverage CockroachDB’s schema features to add a safety net. Below are concrete, language‑agnostic and code‑specific examples.
1. Application‑level bounds checking (Go example)
When handling a user‑supplied amount that will be added to a balance stored as BIGINT, validate the operation using Go’s math package:
package main
import (
"errors"
"math"
)
func AddBalance(current, addition int64) (int64, error) {
if addition > 0 {
if current > math.MaxInt64-addition {
return 0, errors.New("integer overflow: balance would exceed BIGINT max")
}
} else {
if current < math.MinInt64-addition {
return 0, errors.New("integer overflow: balance would go below BIGINT min")
}
}
return current + addition, nil
}
// Usage in an HTTP handler
func depositHandler(w http.ResponseWriter, r *http.Request) {
var req struct { Amount int64 `json:"amount"` }
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
newBal, err := AddBalance(currentBalance, req.Amount)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// INSERT newBal into CockroachDB
}
2. CockroachDB schema guardrails
Add a CHECK constraint to reject out‑of‑range values, providing defense‑in‑depth:
CREATE TABLE accounts (
id BIGINT PRIMARY KEY,
balance BIGINT NOT NULL,
CONSTRAINT chk_balance_range
CHECK (balance >= -9223372036854775808 AND balance <= 9223372036854775807)
);
If the application somehow bypasses validation, CockroachDB will abort the transaction with a clear constraint‑violation error, which can be logged and alerted on.
3. Use safer numeric types when appropriate
For values that may exceed 64‑bit range (e.g., cumulative event counts), consider CockroachDB’s DECIMAL or NUMERIC types, which support arbitrary precision:
CREATE TABLE event_counts (
event_id UUID PRIMARY KEY,
count NUMERIC NOT NULL
);
Then perform arithmetic in the application using a big‑integer library (e.g., math/big in Go) before persisting the result.
By combining rigorous input validation, application‑level overflow checks, and CockroachDB‑native constraints, you eliminate the integer‑overflow attack surface while still benefiting from the database’s strong consistency and performance.