HIGH mass assignmentfibercockroachdb

Mass Assignment in Fiber with Cockroachdb

Mass Assignment in Fiber with Cockroachdb — how this specific combination creates or exposes the vulnerability

Mass Assignment in a Fiber API backed by Cockroachdb occurs when user-supplied JSON or form data maps directly to database columns or struct fields without explicit allowlisting. Because Cockroachdb is compatible with PostgreSQL wire protocol and typical Go ORMs, developers often define models that mirror database columns. If a Fiber handler decodes incoming JSON into a struct or map and then passes that to Cockroachdb without filtering fields, an attacker can set sensitive properties such as is_admin, role_id, or created_at that the application did not intend to be user-controlled.

When these models are reused for both input binding and database operations, the risk is amplified. For example, a user registration handler might bind request body to a User model and then create the record in Cockroachdb using an ORM like GORM. Without explicit field exclusion, an attacker can inject values for fields that influence permissions or tenancy. In multi-tenant schemas, this can lead to BOLA/IDOR where one user modifies another user’s data by changing tenant_id or organization_id fields that were inadvertently exposed through mass assignment.

Because middleBrick tests unauthenticated attack surfaces, it can detect endpoints where mass assignment enables privilege escalation or unauthorized data modification. The scanner checks whether input validation rules align with the fields accepted by the database schema. A mismatch indicates that user input can drive database columns that should be server-controlled, such as timestamps, version numbers, or administrative flags. This is especially critical when combined with Property Authorization checks; if authorization logic relies on properties that can be mass-assigned, the guardrails are bypassed.

Real-world patterns include binding query parameters or JSON bodies directly to SQL rows, using constructs like c.Bind() in Fiber and then calling db.Create(). Without struct tags that specify form or query bindings explicitly, or without using a separate input DTO (data transfer object), the attack surface grows. The presence of Cockroachdb does not change the mechanics of mass assignment, but its distributed SQL semantics and strict consistency can make unintended writes propagate quickly across nodes, increasing impact.

middleBrick’s checks include Input Validation and Property Authorization to surface these risks. It cross-references the OpenAPI spec definitions with runtime behavior to identify endpoints where fields accepted by the API are not explicitly filtered before reaching the database. Remediation guidance focuses on using dedicated input structures, strict binding rules, and server-side field filtering to ensure that only intended data reaches Cockroachdb.

Cockroachdb-Specific Remediation in Fiber — concrete code fixes

To prevent mass assignment in Fiber with Cockroachdb, define separate input and output structs and never bind user input directly to database models. Use explicit JSON tags and validate each field against an allowlist. Below are concrete, working examples.

1. Use distinct input and database structs

Define a request-specific struct that only includes fields the client may set. Then map those fields to your Cockroachdb model explicitly.

// input/dto.go
package input
type CreateUserRequest struct {
	Email string `json:"email" validate:"required,email"`
	Name  string `json:"name" validate:"required,min=1,max=100"`
}

// model/user.go
package model
type User struct {
	ID           int64  `json:"id"`
	Email        string `json:"email"`
	Name         string `json:"name"`
	IsAdmin      bool   `json:"-"`        // excluded from JSON output
	Organization string `json:"organization"`
	CreatedAt    string `json:"created_at"`
}

2. Map and insert with explicit field selection

In your Fiber handler, bind to the input DTO and insert only the fields you trust into Cockroachdb.

// handlers/user.go
package handlers
import (
	"github.com/gofiber/fiber/v2"
	"yourapp/input"
	"yourapp/model"
	"gorm.io/gorm"
)

func CreateUser(c *fiber.Ctx) error {
	var req input.CreateUserRequest
	if err := c.BodyParser(&req); err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
	}

	user := model.User{
		Email:        req.Email,
		Name:         req.Name,
		Organization: "default-org", // server-controlled
		IsAdmin:      false,         // default, not user-provided
	}

	db := c.Locals("db").(*gorm.DB)
	if err := db.Create(&user).Error; err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
	}
	return c.JSON(fiber.Map{"id": user.ID})
}

3. GORM-specific configurations for Cockroachdb

Configure GORM to ignore unset fields and avoid zero-value pollution. Use Select/Preload to control writes.

// db/connect.go
package db
import (
	"gorm.io/driver/postgres"
	"gorm.io/gorm"
)

func Connect() (*gorm.DB, error) {
	dsn := "postgresql://user:pass@host:26257/dbname?sslmode=require"
	conn, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
		SkipDefaultTransaction: true,
	})
	if err != nil {
		return nil, err
	}
	// Ensure zero values are not auto-assigned
	conn.Migrator().SetColumnDefault("users", "is_admin", false)
	return conn, nil
}

4. Validate and sanitize with allowlists

Use a validation library to enforce field-level rules and reject unknown fields. This prevents attackers from adding extra keys that map to sensitive columns.

// middleware/validation.go
package middleware
import (
	"github.com/gofiber/fiber/v2"
	"github.com/go-playground/validator/v10"
)

var validate *validator.Validate

func init() {
	validate = validator.New()
}

func ValidateBody(next *fiber.Handler) {
	return func(c *fiber.Ctx) error {
		if err := validate.Struct(c.Locals("requestBody")); err != nil {
			return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
		}
		return next(c)
	}
}

5. Enforce server-side defaults for sensitive columns

Do not rely on client-supplied values for tenant_id, role, or permissions. Set them server-side based on authentication context or configuration.

// handlers/order.go
package handlers
func CreateOrder(c *fiber.Ctx) error {
	var req input.OrderRequest
	if err := c.BodyParser(&req); err != nil {
		return c.SendStatus(fiber.StatusBadRequest)
	}

	order := model.Order{
		Item:     req.Item,
		Quantity: req.Quantity,
		TenantID: c.Locals("tenant_id"), // injected from auth middleware
	}

	db := c.Locals("db").(*gorm.DB)
	if err := db.Create(&order).Error; err != nil {
		return c.SendStatus(fiber.StatusInternalServerError)
	}
	return c.JSON(fiber.Map{"order_id": order.ID})
}

Related CWEs: propertyAuthorization

CWE IDNameSeverity
CWE-915Mass Assignment HIGH

Frequently Asked Questions

How does middleBrick detect mass assignment risks in Fiber APIs backed by Cockroachdb?
middleBrick runs unauthenticated scans that compare the API's OpenAPI/Swagger definitions with observed input handling. It flags endpoints where fields accepted from the client are not explicitly filtered before being passed to Cockroachdb, indicating potential mass assignment.
Can using separate input DTOs fully prevent mass assignment in Fiber with Cockroachdb?
Using distinct input DTOs is a strong control, but it must be paired with strict binding rules and explicit field mapping to the database model. Always validate with allowlists and exclude sensitive fields from JSON struct tags to ensure they cannot be set by users.