Null Pointer Dereference in Fiber with Cockroachdb
Null Pointer Dereference in Fiber with Cockroachdb
A null pointer dereference in a Fiber service that uses CockroachDB typically occurs when application code treats a database query result or a row value as non-null without validating it first. Because CockroachDB is strongly consistent and supports standard SQL null semantics, a query can legitimately return NULL for a column or an entire row, and Go pointers representing those values will be nil. If Fiber handlers or middleware assume a value is present and dereference that pointer without checking, the service can panic, leading to 500 errors and potential denial of service.
Consider a typical pattern where a handler fetches a user record by ID. The SQL query may return no matching row, and an ORM or database/sql scan will leave pointer fields nil. In Fiber, a panic in a handler propagates to the server unless recovered, breaking availability. This risk is heightened when the route is public or used in high-throughput scenarios, as an unhandled panic can cascade into connection pressure or noisy service metrics.
Additionally, JSON serialization in Fiber can exacerbate the issue. When a struct field is a pointer and its value is nil, encoding/json omits the key or may produce null depending on settings. If downstream consumers expect a concrete value, they might themselves introduce unsafe type assertions or fail to handle null properly, effectively shifting the null pointer dereference into client integrations.
From an API security perspective, null pointer dereferences map to improper error handling and input validation failures under the OWASP API Top 10. An attacker can probe endpoints with crafted identifiers that yield no database rows, triggering repeated panics and exposing timing differences or error messages that aid reconnaissance. While middleBrick does not fix code, its findings highlight categories such as Input Validation and Authentication, emphasizing the need to validate existence and authorization before dereferencing any database result.
In architectures that adopt OpenAPI specifications and leverage tools like the middleBrick CLI to scan endpoints, teams can correlate runtime behavior with schema expectations. For example, if a path parameter is documented as required but the database returns no data for certain values, the handler must return a controlled 404 instead of allowing a nil dereference. Continuous monitoring via the middleBrick Dashboard or automated gates in the GitHub Action can help ensure that new changes do not reintroduce such fragile patterns.
Cockroachdb-Specific Remediation in Fiber
To prevent null pointer dereference in Fiber applications using CockroachDB, always check for SQL empty results and use defensive pointer handling. Prefer value semantics where possible, and when pointers are necessary, validate before dereferencing. Below are concrete, working examples in Go that demonstrate safe querying and response construction.
Safe Row Query with Explicit Nil Checks
When querying a single row, use QueryRow and check for sql.ErrNoRows before accessing fields through pointers.
package main
import (
"context"
"database/sql"
"fmt"
"net/http"
"github.com/gofiber/fiber/v2"
_ "github.com/lib/pq"
)
type User struct {
ID int64 `json:"id"`
Username *string `json:"username"` // pointer to allow nil
Email *string `json:"email"`
}
func getUserHandler(db *sql.DB) fiber.Handler {
return func(c *fiber.Ctx) error {
userID := c.Params("id")
ctx := c.Context()
var u User
row := db.QueryRowContext(ctx, "SELECT id, username, email FROM users WHERE id = $1", userID)
err := row.Scan(&u.ID, &u.Username, &u.Email)
if err != nil {
if err == sql.ErrNoRows {
return c.Status(http.StatusNotFound).JSON(fiber.Map{"error": "user not found"})
}
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": "database error"})
}
// Safe: pointers are guaranteed non-nil because Scan populated them via zero-value fallback
// If columns can be NULL in CockroachDB, use sql.NullString or similar and convert conditionally
return c.JSON(u)
}
}
Handling Nullable Columns with sql.NullString
CockroachDB columns may contain NULL. Use sql.NullString to distinguish between a NULL value and an empty string, and only dereference pointers after confirming validity.
import (
"database/sql"
)
type SafeUser struct {
ID int64 `json:"id"`
Username sql.NullString `json:"username"`
CreatedAt sql.NullTime `json:"created_at"`
}
func getSafeUser(db *sql.DB, userID string) (SafeUser, error) {
var u SafeUser
row := db.QueryRow("SELECT id, username, created_at FROM users WHERE id = $1", userID)
err := row.Scan(&u.ID, &u.Username, &u.CreatedAt)
if err != nil {
return u, err
}
return u, nil
}
// Later in Fiber handler:
if user.Username.Valid {
// Use user.Username.String safely
} else {
// Handle NULL case explicitly
}
Defensive Pointer Dereferencing
If you must keep pointer fields, always check for nil before reading or writing. Combine this with proper HTTP status codes in Fiber to ensure predictable behavior.
func respondUsername(c *fiber.Ctx, u *User) error {
if u == nil {
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "user unavailable"})
}
if u.Username == nil {
return c.SendStatus(fiber.StatusNoContent)
}
return c.JSON(fiber.Map{"username": *u.Username})
}
For teams using the middleBrick CLI, these patterns reduce the likelihood of findings related to Input Validation and Authentication. The Pro plan’s continuous monitoring can alert you when new endpoints introduce risky pointer handling, while the GitHub Action can gate merges if scans detect regression-prone code patterns.