Clickjacking in Fiber with Cockroachdb
Clickjacking in Fiber with Cockroachdb — how this specific combination creates or exposes the vulnerability
Clickjacking is a client-side UI redress attack where an attacker tricks a user into interacting with a hidden or disguised element inside an invisible or overlaying page. In a Fiber application that uses CockroachDB as the backend datastore, the vulnerability arises when pages render dynamic data from CockroachDB without enforcing strict framing controls or context-aware authorization. For example, a dashboard rendered by Fiber might pull sensitive account information from CockroachDB and display it in an iframe or partial view; if the response lacks Content-Security-Policy frame-ancestors rules or X-Frame-Options, an attacker can embed that view inside a malicious page and capture user interactions.
Consider a scenario where a Fiber route queries CockroachDB for a user’s profile and renders it as JSON or HTML without validating the request origin. An attacker can craft a page that loads this route inside a transparent iframe and overlays interactive elements (e.g., buttons or links) on top of it. When the user is authenticated to the Fiber app, their credentials or session cookies may be included automatically by the browser, allowing the attacker to perform actions on behalf of the victim using data retrieved from CockroachDB. Because CockroachDB often stores sensitive user data, exposure of this data through an embedded view can lead to account takeover or data leakage if anti-clickjacking protections are missing.
Additionally, if the Fiber application exposes an unauthenticated API endpoint that reads from CockroachDB and embeds responses in iframes—such as a public report or widget—attackers can directly embed these endpoints without any user context, making clickjacking trivial. The risk is compounded when the application relies on implicit trust of the Referer header or does not validate the Origin header for state-changing requests originating from embedded contexts. Proper mitigation requires a defense-in-depth approach: enforcing frame-ancestors policies, validating request origins, and ensuring that sensitive data fetched from CockroachDB is never rendered in a context that can be embedded by third parties.
Cockroachdb-Specific Remediation in Fiber — concrete code fixes
To mitigate clickjacking in a Fiber application that interacts with CockroachDB, implement strict framing controls and origin validation. Below are concrete code examples using Fiber and CockroachDB drivers for Go.
1. Set Security Headers to Prevent Embedding
Ensure every response includes X-Frame-Options and Content-Security-Policy headers to restrict which origins can embed the page.
package main
import (
"github.com/gofiber/fiber/v2"
"github.com/jackc/pgx/v5/pgxpool"
)
func main() {
app := fiber.New()
// Connect to CockroachDB
pool, _ := pgxpool.New(app.Context(), "postgres://user:pass@localhost:26257/defaultdb?sslmode=require")
defer pool.Close()
app.Use(func(c *fiber.Ctx) error {
c.Set("X-Frame-Options", "DENY")
c.Set("Content-Security-Policy", "frame-ancestors 'none'; script-src 'self'; connect-src 'self'")
return c.Next()
})
app.Get("/profile", func(c *fiber.Ctx) error {
userID := c.Params("id")
var name, email string
err := pool.QueryRow(c.Context(), "SELECT name, email FROM users WHERE id = $1", userID).Scan(&name, &email)
if err != nil {
return c.Status(fiber.StatusInternalServerError).SendString("Database error")
}
return c.JSON(fiber.Map{"name": name, "email": email})
})
app.Listen(":3000")
}
2. Validate Origin for State-Changing Requests
For endpoints that modify data (e.g., POST/PUT/DELETE), validate the Origin or Referer header to ensure requests come from your trusted domain.
func verifyOrigin(next fiber.Handler) fiber.Handler {
return func(c *fiber.Ctx) error {
origin := c.Get("Origin")
if origin != "https://your-trusted-domain.com" {
return c.Status(fiber.StatusForbidden).SendString("Invalid request origin")
}
return next(c)
}
}
app.Post("/update-profile", verifyOrigin, func(c *fiber.Ctx) error {
userID := c.Params("id")
var payload struct {
Name string
Email string
}
if err := c.BodyParser(&payload); err != nil {
return c.Status(fiber.StatusBadRequest).SendString("Invalid payload")
}
_, err := pool.Exec(c.Context(), "UPDATE users SET name = $1, email = $2 WHERE id = $3", payload.Name, payload.Email, userID)
if err != nil {
return c.Status(fiber.StatusInternalServerError).SendString("Update failed")
}
return c.SendStatus(fiber.StatusOK)
})
3. Avoid Embedding Sensitive Data in Iframes
Never render data fetched from CockroachDB inside iframes or objects. If you must display reports, serve them with restrictive CSP and ensure they are not accessible via embedded contexts.
app.Get("/report/:id", func(c *fiber.Ctx) error {
reportID := c.Params("id")
var content string
err := pool.QueryRow(c.Context(), "SELECT content FROM reports WHERE id = $1", reportID).Scan(&content)
if err != nil {
return c.Status(fiber.StatusNotFound).SendString("Report not found")
}
// Serve as plain HTML with strict CSP; do not allow framing
return c.SendString("<!DOCTYPE html><html><head><meta http-equiv=\"Content-Security-Policy\" content=\"frame-ancestors 'none';\"></head><body>" + content + "</body></html>")
})
By combining these patterns—security headers, origin validation, and careful rendering—you reduce the attack surface for clickjacking in Fiber apps backed by CockroachDB. Always treat data from CockroachDB as sensitive and ensure it is never exposed in an embeddable context without explicit protective controls.