MEDIUM clickjackingfeathersjscockroachdb

Clickjacking in Feathersjs with Cockroachdb

Clickjacking in Feathersjs with Cockroachdb — how this specific combination creates or exposes the vulnerability

Clickjacking is a client-side attack where an attacker tricks a user into interacting with a hidden or disguised UI element inside an embedded frame. In a Feathersjs application backed by Cockroachdb, the risk arises when responses render data-driven UI components without anti-clickjacking protections and the service exposes endpoints that return sensitive or actionable data that can be invoked cross-origin. Feathersjs, by default, does not set HTTP headers such as X-Frame-Options or Content-Security-Policy frame-ancestors, and if the app serves pages or iframes that display data retrieved from Cockroachdb (for example, user-specific records or admin actions), an attacker can embed the endpoint in a malicious page and overlay invisible controls to perform unauthorized actions on behalf of the authenticated user.

When Cockroachdb is the backend store, the impact is amplified if queries reflect attacker-controlled input without strict authorization checks (e.g., a /users/:id/profile endpoint that directly uses an ID parameter without verifying ownership). An attacker can craft a page that embeds this Feathersjs endpoint inside an iframe, overlaying interactive elements to trigger profile updates or data exports via the user’s authenticated session. Because Cockroachdb retains strong consistency and transactional semantics across nodes, any injected changes can propagate quickly, increasing the potential for unauthorized operations to persist. The combination of Feathersjs services, which often expose REST and real-time channels, with a distributed SQL store like Cockroachdb means that if clickjacking vectors exist, they can lead to unintended mutations, data exposure, or privilege escalation across tenants or user contexts.

Additionally, if the Feathersjs app serves an admin dashboard or a management UI that pulls live data from Cockroachdb and embeds it in iframes or widgets, the absence of frame-busting or CSP frame-ancestors directives enables clickjacking scenarios where an attacker can simulate clicks on admin actions (such as creating roles or modifying permissions). Even if the API itself enforces authentication, the browser context can be manipulated, allowing the attacker to leverage the victim’s permissions to interact with Cockroachdb-backed resources. Therefore, securing the HTTP layer and ensuring strict CSP policies are critical to mitigating clickjacking in this stack.

Cockroachdb-Specific Remediation in Feathersjs — concrete code fixes

Remediation centers on enforcing frame-ancestors policies and validating data ownership in Feathersjs hooks and services. Below are concrete code examples for a Feathersjs service that queries Cockroachdb using a Node.js client, with protections tailored to this combination.

1. Set CSP and X-Frame-Options headers

Apply security headers at the Feathersjs server level to prevent embedding. For an Express-based Feathers app:

const feathers = require('@feathersjs/feathers');
const express = require('@feathersjs/express');
const app = express(feathers());

// Security headers to mitigate clickjacking
app.use((req, res, next) => {
  res.setHeader('X-Frame-Options', 'DENY');
  res.setHeader('Content-Security-Policy', "frame-ancestors 'none'");
  next();
});

// Your Feathers services and hooks
app.configure(express.rest());
app.configure(express.socketio());

app.listen(3030);

2. Enforce ownership checks in Cockroachdb queries

Ensure that endpoints retrieving or modifying data validate that the resource belongs to the requesting user. Using a Cockroachdb client (e.g., node-postgres) within a Feathers hook:

const { Pool } = require('pg');
const pool = new Pool({
  connectionString: 'postgresql://user:password@host:26257/db?sslmode=require',
});

// Feathers hook to validate data ownership before proceeding
function checkCockroachdbOwnership(context) {
  return async context => {
    const { id } = context.params.query; // or context.id for find/update/remove
    const user = context.params.user; // authenticated user from auth hook
    if (!id || !user) return context;

    const { rows } = await pool.query(
      'SELECT user_id FROM accounts WHERE id = $1 FOR SHARE',
      [id]
    );
    if (rows.length === 0) {
      throw new Error('Record not found');
    }
    if (rows[0].user_id !== user.id) {
      throw new Error('Unauthorized: record does not belong to user');
    }
    return context;
  };
}

// Apply in service hooks
app.service('accounts').hooks({
  before: {
    get: [checkCockroachdbOwnership],
    find: [checkCockroachdbOwnership],
  },
});

3. Parameterized queries to prevent injection and enforce scoping

Always use parameterized SQL to avoid injection that could bypass ownership checks. Example for retrieving a user profile tied to Cockroachdb:

app.service('profiles').hooks({
  before: {
    async get(context) {
      const { user } = context.params;
      const { id } = context.params.query;
      const { rows } = await pool.query(
        'SELECT id, display_name, email FROM profiles WHERE id = $1 AND user_id = $2',
        [id, user.id]
      );
      if (rows.length === 0) {
        throw new Error('Profile not found or access denied');
      }
      context.result = rows[0];
      return context;
    },
  },
});

4. Real-time channels validation

If using Feathers real-time sockets with Cockroachdb-backed state, validate events to ensure clients cannot impersonate others. For a chat service:

app.channel('chatrooms').hooks({
  join: async context => {
    const { user } = context.params;
    const { roomId } = context.params.query;
    const { rows } = await pool.query(
      'SELECT user_id FROM room_members WHERE room_id = $1 AND user_id = $2',
      [roomId, user.id]
    );
    if (rows.length === 0) {
      throw new Error('Not a member of this room');
    }
    return context;
  },
});

These measures ensure that even if an attacker attempts clickjacking via embedded frames, the CSP and X-Frame-Options headers prevent rendering, while Cockroachdb queries enforce strict ownership checks, reducing the impact of cross-origin interactions.

Frequently Asked Questions

How does middleBrick detect clickjacking risks in a Feathersjs + Cockroachdb setup?
middleBrick runs 12 parallel security checks including Authentication, BOLA/IDOR, and Unsafe Consumption. It analyzes OpenAPI specs and runtime behavior to identify missing security headers like X-Frame-Options and CSP frame-ancestors, and flags endpoints that expose sensitive actions without ownership validation against Cockroachdb-backed resources.
Can middleBrick test LLM security for apps using Feathersjs and Cockroachdb?
Yes. middleBrick’s unique LLM/AI Security checks include system prompt leakage detection, active prompt injection testing, output scanning for PII and API keys, and excessive agency detection. These checks apply regardless of backend datastore, so Cockroachdb-driven Feathersjs APIs are covered.