MEDIUM clickjackingnestjsbearer tokens

Clickjacking in Nestjs with Bearer Tokens

Clickjacking in Nestjs with Bearer Tokens — 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 overlapped frame. In a NestJS application that uses Bearer Tokens for authentication, clickjacking can amplify the impact of token theft or unauthorized actions even when the token itself is transmitted securely over HTTPS. Bearer Tokens are typically stored in browser storage (localStorage/sessionStorage) or in secure, HttpOnly cookies. When a page is embedded inside an iframe on a malicious site, the user’s authenticated session can be abused if the application lacks appropriate frame-protection headers.

NestJS does not automatically set frame-protection headers; developers must explicitly configure HTTP headers in the application layer. Without X-Frame-Options or Content-Security-Policy (CSP) frame-ancestors directives, an attacker can embed the protected page in an iframe and use UI overlays to manipulate user interactions. For example, a user who is authenticated via a Bearer Token (e.g., after logging in and storing the token) might unknowingly click a button or form element inside the invisible iframe, triggering state-changing requests that are automatically authorized by the browser due to the valid session token. The token itself is not leaked directly by clickjacking, but the induced actions can lead to unauthorized operations such as changing email, updating settings, or initiating transactions.

The risk is especially pronounced in SPAs (Single Page Applications) built with NestJS backends where Bearer Tokens are passed via the Authorization header. If the frontend routes are not guarded against being rendered inside an external frame, an attacker can craft a malicious site that loads the legitimate app inside an iframe, sets transparent overlays, and simulates user interactions. Since the browser includes cookies and authorization headers automatically with each request, the forged actions appear legitimate to the backend. This makes clickjacking a complementary vector to Bearer Token–based authentication when defenses are incomplete.

To identify this during a scan, middleBrick runs checks that analyze response headers and CSP configurations, correlating the absence of frame-protection mechanisms with authentication methods such as Bearer Tokens. The scanner flags scenarios where authenticated pages are embeddable, highlighting the potential for UI-based abuse even though the token transmission remains secure. This emphasizes the need to harden the NestJS application’s HTTP layer alongside token handling practices.

Bearer Tokens-Specific Remediation in Nestjs — concrete code fixes

Remediation centers on enforcing frame-protection headers and tightening CSP so that pages or API responses are not embeddable. For NestJS, you can set security headers via middleware or a global guard. Below are concrete, syntactically correct examples that combine Bearer Token handling with clickjacking defenses.

1. Setting X-Frame-Options in NestJS middleware

This approach ensures that browsers refuse to render the response in an iframe, mitigating classic clickjacking.

import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

@Injectable()
export class SecurityMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    // Prevent embedding in any frame
    res.setHeader('X-Frame-Options', 'DENY');
    // Alternatively, allow specific origins:
    // res.setHeader('X-Frame-Options', 'SAMEORIGIN');
    next();
  }
}

Register the middleware in your main application file:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { SecurityMiddleware } from './security.middleware';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.use(new SecurityMiddleware());
  await app.listen(3000);
}
bootstrap();

2. Content-Security-Policy frame-ancestors in NestJS

CSP provides more granular control, allowing you to specify which origins can embed the page. This is preferred over X-Frame-Options when you need flexibility.

import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

@Injectable()
export class CspMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    // Allow embedding only from same origin
    res.setHeader(
      'Content-Security-Policy',
      "frame-ancestors 'self'",
    );
    // For multiple specific origins:
    // res.setHeader(
    //   'Content-Security-Policy',
    //   "frame-ancestors 'self' https://trusted.example.com",
    // );
    next();
  }
}

Combine this with secure Bearer Token handling. Ensure tokens are not exposed in URLs or logs, and are sent via the Authorization header:

// Example of a guarded route using Bearer Token in NestJS
import { Controller, Get, Request, Header } from '@nestjs/common';

@Controller('api/me')
export class MeController {
  @Get()
  getMe(@Request() req: Request) {
    // The token is expected in the Authorization header
    const token = req.headers.authorization?.split(' ')[1];
    if (!token) {
      throw new Error('Unauthorized');
    }
    // Validate token (e.g., via JWT service) and proceed
    return { message: 'Authenticated user data' };
  }
}

3. Layered approach for SPAs and APIs

For APIs consumed by frontends, ensure that CORS and CSP are aligned. Do not allow * for frame-ancestors or overly permissive CORS origins when Bearer Tokens are in use.

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { CspMiddleware } from './csp.middleware';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  // Ensure CORS is configured tightly when using Bearer Tokens
  app.enableCors({
    origin: true,
    credentials: true,
  });
  app.use(new CspMiddleware());
  await app.listen(3000);
}
bootstrap();

These configurations ensure that even if a Bearer Token is present, the page cannot be hijacked via clickjacking techniques. middleBrick scans verify that such headers are present and flags missing protections, helping you align with OWASP API Security Top 10 and related compliance frameworks.

Frequently Asked Questions

Can clickjacking lead to Bearer Token leakage in NestJS applications?
Clickjacking does not directly leak Bearer Tokens, but it can trick users into performing authenticated actions that expose data or change state. Defense-in-depth with frame-protection headers is essential to prevent UI-based abuse.
How does middleBrick detect clickjacking risks in NestJS APIs with Bearer Tokens?
middleBrick checks response headers for missing X-Frame-Options and Content-Security-Policy frame-ancestors directives, correlating these with authentication mechanisms like Bearer Tokens to highlight embeddable pages that are vulnerable to UI redress attacks.