Data Exposure in Fiber with Cockroachdb
Data Exposure in Fiber with Cockroachdb — how this specific combination creates or exposes the vulnerability
Data exposure in a Fiber API that uses CockroachDB typically occurs when responses include database fields that should remain restricted. Because CockroachDB uses the PostgreSQL wire protocol and shares many SQL behaviors with PostgreSQL, developers often treat it like PostgreSQL but may miss subtle differences in default drivers or connection handling. When endpoints construct HTTP responses by directly serializing query results into JSON, fields such as internal identifiers, hashed credentials, or audit columns can unintentionally appear in the payload.
In a black-box scan, middleBrick tests unauthenticated endpoints that accept an identifier (for example, a user ID) and observe whether the returned JSON contains sensitive database fields. With CockroachDB, if the application uses a generic ORM or raw SQL without column-level filtering, an endpoint like GET /users/:id can return columns such as password_hash, email, or created_at when those columns exist in the table but should be omitted from the API response. This becomes a data exposure finding because the API surface reveals internal schema details that can aid an attacker in planning further exploitation.
The risk is compounded when the Fiber application does not enforce field-level authorization. For instance, an endpoint might fetch a row with SELECT * from a CockroachDB table and return it as JSON. Even if the database enforces row-level security, the API should also enforce which fields are allowed to leave the service. Without explicit projection in the SQL query or explicit struct filtering in Go, sensitive columns can leak into responses. middleBrick’s Data Exposure check flags these scenarios by comparing the returned JSON against a baseline of expected, non-sensitive fields and by detecting the presence of high-sensitivity column names in unauthenticated responses.
When combined with other checks such as BOLA/IDOR, data exposure can enable horizontal privilege escalation. An attacker who learns that a response includes a role or tenant_id field can manipulate identifiers to access data belonging to other tenants or roles. Because CockroachDB supports complex queries and secondary indexes, an improperly constrained endpoint can expose relationships between records that should remain isolated. The scanner highlights these patterns by correlating response fields with known sensitive keywords and by testing whether changing resource identifiers yields data belonging to other users or organizations.
To illustrate, consider a Fiber route written in Go that queries CockroachDB without column restriction:
// Example vulnerable pattern
user := User{}
if err := db.QueryRow(context.Background(), "SELECT * FROM users WHERE id = $1", id).Scan(
&user.ID, &user.Email, &user.PasswordHash, &user.Role, &user.CreatedAt,
); err != nil {
c.Status(500).JSON(H{"error": err.Error()})
return
}
c.JSON(200, user)
If the User struct includes PasswordHash and Role, and the endpoint does not strip these fields before serialization, a middleBrick scan can detect the exposure. The fix is to select only required columns and to use a response-specific struct that omits sensitive fields.
Cockroachdb-Specific Remediation in Fiber — concrete code fixes
Remediation centers on explicit column selection in SQL and strict struct definitions that exclude sensitive fields from HTTP responses. Because CockroachDB behaves like PostgreSQL, using database/sql with the lib/pq or pgx driver remains valid, but you must avoid SELECT * and instead enumerate only the columns you intend to expose.
First, define separate domain and response structures. The domain struct may include sensitive fields for database operations, while the response struct includes only safe fields:
// domain models used for DB interaction
type UserRecord struct {
ID int64
Email string
PasswordHash string
Role string
CreatedAt time.Time
}
// response models used for API output
type UserResponse struct {
ID int64 `json:"id"`
Email string `json:"email"`
CreatedAt time.Time `json:"created_at"`
}
Second, construct SQL queries that select only the necessary columns and map them into the domain struct. Then convert to the response struct before sending JSON:
func getUser(c fiber.Ctx) error {
id := c.Params("id")
var rec UserRecord
// Explicit column list prevents accidental exposure of PasswordHash and Role
err := db.QueryRow(context.Background(),
"SELECT id, email, created_at FROM users WHERE id = $1", id,
).Scan(&rec.ID, &rec.Email, &rec.CreatedAt)
if err != nil {
return c.Status(500).JSON(H{"error": "unable to fetch user"})
}
resp := UserResponse{
ID: rec.ID,
Email: rec.Email,
CreatedAt: rec.CreatedAt,
}
return c.JSON(200, resp)
}
Third, if you must retrieve broader data for internal processing, ensure sensitive fields are omitted at serialization time by using struct embedding or custom JSON tags that exclude fields:
type SafeUser struct {
ID int64 `json:"id"`
Email string `json:"email"`
CreatedAt time.Time `json:"created_at"`
// PasswordHash and Role are intentionally excluded
}
Fourth, validate incoming identifiers to prevent IDOR-style manipulations that could change which CockroachDB row is fetched. While this does not directly stop data exposure, it reduces the attack surface that an exposed column could amplify:
if id == "" {
return c.Status(400).JSON(H{"error": "missing user identifier"})
}
Finally, review your connection string and driver settings to ensure CockroachDB-specific TLS and authentication options are enforced, as insecure configurations can increase the impact of data exposure. Use environment-driven configuration rather than hard-coded values, and verify that your queries do not inadvertently return additional rows or columns through joins or ORM defaults.
Related CWEs: dataExposure
| CWE ID | Name | Severity |
|---|---|---|
| CWE-200 | Exposure of Sensitive Information | HIGH |
| CWE-209 | Error Information Disclosure | MEDIUM |
| CWE-213 | Exposure of Sensitive Information Due to Incompatible Policies | HIGH |
| CWE-215 | Insertion of Sensitive Information Into Debugging Code | MEDIUM |
| CWE-312 | Cleartext Storage of Sensitive Information | HIGH |
| CWE-359 | Exposure of Private Personal Information (PII) | HIGH |
| CWE-522 | Insufficiently Protected Credentials | CRITICAL |
| CWE-532 | Insertion of Sensitive Information into Log File | MEDIUM |
| CWE-538 | Insertion of Sensitive Information into Externally-Accessible File | HIGH |
| CWE-540 | Inclusion of Sensitive Information in Source Code | HIGH |