HIGH cross site request forgeryfibermongodb

Cross Site Request Forgery in Fiber with Mongodb

Cross Site Request Forgery in Fiber with Mongodb — how this specific combination creates or exposes the vulnerability

Cross Site Request Forgery (CSRF) in a Fiber-based API becomes notable when endpoints mutate state and rely on session cookies for identity without additional verification. When your Fiber service uses cookie-based sessions and communicates with MongoDB, an attacker can trick a logged-in user’s browser into issuing authenticated requests to those Fiber endpoints. Because the browser automatically includes cookies, the server may process state-changing operations (e.g., updating or deleting a document) using the victim’s MongoDB permissions, leading to unauthorized changes in MongoDB collections.

Consider a typical pattern: a Fiber route reads and writes user data from a MongoDB collection using a decoded user ID from session cookies. If the route does not validate the intent of the request with a CSRF token or a same-site/cors policy, an attacker can craft a malicious site that sends a POST or PUT request to that route. The request will carry the user’s cookies, and the server will apply the operation to MongoDB on behalf of the user, because the server trusts the cookie and does not re-evaluate whether the request was intentionally initiated by the user. This becomes more impactful when MongoDB documents contain sensitive fields (e.g., roles, permissions, or PII), and the compromised write can escalate privileges or exfiltrate data.

Moreover, if your Fiber application exposes an endpoint that accepts an _id from the request body or URL parameters to locate and update a MongoDB document, a CSRF attack can manipulate that identifier. For example, an attacker might cause the victim’s browser to submit a request that updates the victim’s profile or changes authentication settings in MongoDB. Because the request appears to come from the user’s browser with valid session cookies, the server does not detect the malicious intent. The combination of Fiber’s fast routing, cookie-based sessions, and direct MongoDB updates without anti-CSRF controls creates a path for unauthorized state changes in the database.

Notably, CSRF risk here is tied to how authentication and state are managed, not to a flaw in MongoDB itself. If your API uses token-based authentication (e.g., bearer tokens in Authorization headers) and does not rely on cookies, the typical browser-based CSRF vector is less effective because attackers cannot easily set arbitrary Authorization headers cross-origin. However, when cookies are used, proper defenses such as SameSite cookie attributes, CSRF tokens, and strict CORS configuration are essential to prevent malicious requests from reaching your Fiber handlers and affecting MongoDB operations.

Mongodb-Specific Remediation in Fiber — concrete code fixes

To mitigate CSRF in a Fiber application that uses MongoDB, implement defenses that break the automatic credential send in browsers and validate request intent. Below are concrete code examples using the MongoDB Go driver with Fiber.

1. Use SameSite cookies and secure cookie attributes

Set SameSite cookies to prevent the browser from sending cookies in cross-site requests. Combine Secure and HttpOnly for additional protection.

package main

import (
	"github.com/gofiber/fiber/v2"
)

func main() {
	app := fiber.New()

	app.Get("/login", func(c *fiber.Ctx) error {
		// Set a session cookie with SameSite=Lax (or Strict for higher security)
		return c.Cookie(&fiber.Cookie{
			Name:     "session_id",
			Value:    "some-session-handle",
			Expires:  time.Now().Add(24 * time.Hour),
			HTTPOnly: true,
			Secure:   true,
			SameSite: fiber.CookieSameSiteLaxMode,
		})
	})

	app.Listen(":3000")
}

2. Require CSRF tokens for state-changing routes

Issue a synchronizer token pattern: generate a per-session token, store it server-side (e.g., in MongoDB), and require it for POST/PUT/DELETE operations that affect MongoDB documents.

package main

import (
	"context"
	"crypto/rand"
	"encoding/hex"
	"net/http"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"github.com/gofiber/fiber/v2"
)

func generateCSRFToken() (string, error) {
	b := make([]byte, 16)
	if _, err := rand.Read(b); err != nil {
		return "", err
	}
	return hex.EncodeToString(b), nil
}

func main() {
	ctx := context.Background()
	client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
	if err != nil {
		panic(err)
	}
	defer client.Disconnect(ctx)
	coll := client.Database("appdb").Collection("users")

	app := fiber.New()

	app.Get("/form", func(c *fiber.Ctx) error {
		token, err := generateCSRFToken()
		if err != nil {
			return c.SendStatus(http.StatusInternalServerError)
		}
		// Store token in MongoDB associated with the user/session
		_, err = coll.UpdateOne(ctx,
			bson.M{"_id": c.Locals("userID")},
			bson.M{"$set": bson.M{"csrf_token": token}},
		)
		if err != nil {
			return c.SendStatus(http.StatusInternalServerError)
		}
		// Include token in form or header for client to return
		return c.JSON(fiber.Map{"csrf_token": token})
	})

	app.Post("/update-profile", func(c *fiber.Ctx) error {
		var req struct {
			Name  string `json:"name"`
			Token string `json:"csrf_token"`
		}
		if err := c.BodyParser(&req); err != nil {
			return c.SendStatus(http.StatusBadRequest)
		}

		var stored bson.M
		if err := coll.FindOne(ctx, bson.M{"_id": c.Locals("userID")}).Decode(&stored); err != nil {
			return c.SendStatus(http.StatusUnauthorized)
		}
		expected, ok := stored["csrf_token"].(string)
		if !ok || expected != req.Token {
			return c.SendStatus(http.StatusForbidden)
		}

		// Proceed to update MongoDB safely
		_, err := coll.UpdateOne(ctx,
			bson.M{"_id": c.Locals("userID")},
			bson.M{"$set": bson.M{"name": req.Name}},
		)
		if err != nil {
			return c.SendStatus(http.StatusInternalServerError)
		}
		return c.SendStatus(http.StatusOK)
	})

	app.Listen(":3000")
}

3. Configure CORS to restrict origins

Limit which origins can call your Fiber endpoints to reduce CSRF surface.

package main

import (
	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/cors"
)

func main() {
	app := fiber.New()

	app.Use(cors.New(cors.Config{
		AllowOrigins:     "https://yourtrusted.com",
		AllowMethods:     "GET,POST,PUT,DELETE",
		AllowHeaders:     "Origin, Content-Type, Accept",
		ExposeHeaders:    "Content-Length",
		AllowCredentials: true,
		MaxAge:           3600,
	}))

	app.Post("/data", func(c *fiber.Ctx) error {
		// Handle request — only trusted origins can make authenticated requests
		return c.JSON(fiber.Map{"ok": true})
	})

	app.Listen(":3000")
}

4. Validate and sanitize MongoDB update inputs

Ensure that user-controlled values cannot inject unexpected operators or alter unintended documents. Use explicit field selection and avoid passing raw user input directly into update pipelines.

package main

import (
	"context"
	"net/http"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"github.com/gofiber/fiber/v2"
)

func main() {
	ctx := context.Background()
	client, _ := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
	coll := client.Database("appdb").Collection("items")

	app := fiber.New()

	app.Put("/item/:id", func(c *fiber.Ctx) error {
		id := c.Params("id")
		var body struct {
			Name string `json:"name"`
		}
		if err := c.BodyParser(&body); err != nil {
			return c.SendStatus(http.StatusBadRequest)
		}
		// Validate and sanitize input before using in MongoDB update
		if body.Name == "" || len(body.Name) > 100 {
			return c.SendStatus(http.StatusBadRequest)
		}

		result, err := coll.UpdateOne(ctx,
			bson.M{"_id": id, "owner": c.Locals("userID")},
			bson.M{"$set": bson.M{"name": body.Name}},
		)
		if err != nil || result.MatchedCount == 0 {
			return c.SendStatus(http.StatusForbidden)
		}
		return c.JSON(fiber.Map{"matched": result.MatchedCount})
	})

	app.Listen(":3000")
}

Frequently Asked Questions

Does using MongoDB change the CSRF risk in Fiber APIs?
MongoDB itself does not introduce CSRF; the risk arises when Fiber endpoints that mutate MongoDB rely on cookies for authentication without anti-CSRF controls. The database receives whatever identity the server attributes to the request, so server-side protections (SameSite cookies, CSRF tokens, CORS) remain essential.
Can token-based auth remove CSRF concerns when using MongoDB with Fiber?
Yes. If your API uses bearer tokens in the Authorization header and does not rely on cookies for authentication, typical browser-based CSRF attacks are much harder to execute because attackers cannot set arbitrary Authorization headers cross-origin. However, continue to validate origins and inputs to protect other threats.