Clickjacking in Feathersjs
How Clickjacking Manifests in Feathersjs
Clickjacking in Feathersjs applications typically occurs when the framework's default behavior allows embedding Feathersjs API endpoints or admin interfaces within malicious iframes. Feathersjs applications often expose real-time APIs via Socket.io or REST endpoints that, when rendered in a browser, can be framed without restriction. This creates opportunities for attackers to craft deceptive pages that overlay transparent elements on top of legitimate Feathersjs admin panels, authentication forms, or data management interfaces.
The vulnerability is particularly dangerous in Feathersjs because the framework's real-time capabilities make it attractive for building interactive admin dashboards. An attacker could create a malicious site that loads a victim's Feathersjs admin interface in an invisible iframe, then overlay convincing UI elements that trick users into clicking buttons they believe are performing legitimate actions. For instance, a fake 'Delete All Users' button might be positioned directly over what appears to be a 'Save Changes' button in the Feathersjs admin panel.
Feathersjs's default Express.js integration doesn't include clickjacking protections. When you create a Feathersjs application using feathers generate app, the generated Express server doesn't set the X-Frame-Options header or Content-Security-Policy directives that would prevent iframe embedding. This means any Feathersjs application is vulnerable by default unless developers explicitly add these protections.
The issue becomes more severe when Feathersjs applications expose sensitive operations through REST endpoints that don't require authentication for certain requests, or when they use permissive CORS configurations. An attacker could combine clickjacking with other vulnerabilities to execute unauthorized operations on behalf of authenticated users who visit malicious sites while their Feathersjs admin session is active.
Real-time Feathersjs services using Socket.io are especially vulnerable because they maintain persistent connections. An attacker could keep a hidden iframe connection alive to a victim's Feathersjs service, monitoring events and potentially triggering real-time actions through the deceptive overlay interface.
Feathersjs-Specific Detection
Detecting clickjacking vulnerabilities in Feathersjs applications requires examining both the HTTP response headers and the application's configuration. The primary indicator is the absence of X-Frame-Options headers in HTTP responses from your Feathersjs endpoints. You can test this using curl or a browser's developer tools by examining the response headers when accessing any Feathersjs route.
curl -I http://your-feathersjs-app.com/services/usersLook for X-Frame-Options, Content-Security-Policy, or frame-ancestors directives. Their absence indicates vulnerability.
middleBrick's automated scanning specifically tests for clickjacking vulnerabilities in Feathersjs applications by attempting to frame the target URL and checking for these security headers. The scanner evaluates whether your Feathersjs endpoints can be embedded in iframes, which is the fundamental test for clickjacking susceptibility. middleBrick runs this check across all exposed Feathersjs routes, including real-time Socket.io endpoints and REST services.
Another detection method involves testing your Feathersjs application's admin interfaces. If you have authentication-enabled admin panels built with Feathersjs, try embedding them in an iframe on a different domain. If the content loads without restrictions, you have a clickjacking vulnerability. This is particularly important for Feathersjs applications that use the feathers-authentication-local or feathers-authentication-jwt packages, as these interfaces often handle sensitive operations.
middleBrick also checks for related vulnerabilities that compound clickjacking risks in Feathersjs, such as missing CSRF protection on state-changing operations and overly permissive CORS configurations. The scanner's 12 security checks include specific tests for authentication bypasses that could be exploited when combined with clickjacking attacks.
For comprehensive detection, middleBrick can scan your entire Feathersjs application stack, including any OpenAPI specifications that document your API endpoints. The scanner cross-references the documented endpoints with actual runtime behavior to identify inconsistencies that might indicate security misconfigurations.
Feathersjs-Specific Remediation
Remediating clickjacking vulnerabilities in Feathersjs applications requires configuring HTTP security headers at the Express.js level, since Feathersjs builds on top of Express. The most effective approach is to set the X-Frame-Options header to 'DENY' or 'SAMEORIGIN' in your Feathersjs application's main server file.
// src/index.js or wherever your Feathersjs app is configured
const express = require('express');
const feathers = require('@feathersjs/feathers');
const expressRest = require('@feathersjs/express');
const path = require('path');
const app = express(feathers());
// Set clickjacking protection headers
app.use((req, res, next) => {
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('Content-Security-Policy', "frame-ancestors 'none'");
next();
});
// Your existing Feathersjs setup
app.configure(expressRest.rest());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, '../public')));
// ... rest of your Feathersjs configuration
This configuration ensures that all Feathersjs endpoints, including real-time Socket.io connections, reject iframe embedding attempts. The 'DENY' value is the most restrictive and prevents framing from any origin, while 'SAMEORIGIN' allows framing only from the same domain.
For Feathersjs applications that need to be framed for legitimate reasons (such as embedded dashboards), you can use a more nuanced approach with the Content-Security-Policy frame-ancestors directive:
app.use((req, res, next) => {
// Allow framing only from specific trusted domains
res.setHeader('Content-Security-Policy', "frame-ancestors https://trusted.example.com https://app.yourdomain.com");
next();
});lockquote>
This approach provides granular control over which domains can frame your Feathersjs content while blocking all others.
Another Feathersjs-specific consideration is protecting real-time Socket.io connections from clickjacking. Since Socket.io maintains persistent connections, you should configure it to reject connections from unauthorized origins:
const socketio = require('socket.io');
const io = socketio(server, {
cors: {
origin: process.env.ALLOWED_ORIGINS ? process.env.ALLOWED_ORIGINS.split(',') : ['http://localhost:3000'],
methods: ["GET", "POST"]
}
});
// Add clickjacking headers to Socket.io HTTP upgrades
io.engine.on('connection', (socket) => {
socket.conn.socket.setNoDelay(true);
socket.conn.socket.setKeepAlive(true, 60000);
});
For Feathersjs applications using the feathers-authentication-jwt package, ensure that your authentication middleware runs before any sensitive operations and that clickjacking headers are set early in the request pipeline to prevent any window of vulnerability.
middleBrick's remediation guidance for Feathersjs applications includes specific code examples like these, tailored to the framework's architecture. The scanner's findings map directly to these fixes, helping developers understand exactly which headers and configurations need to be added to their Feathersjs applications.