MEDIUM clickjackingstrapihmac signatures

Clickjacking in Strapi with Hmac Signatures

Clickjacking in Strapi with Hmac Signatures — how this specific combination creates or exposes the vulnerability

Clickjacking relies on tricking a user into interacting with a hidden or disguised UI element inside an iframe. When Strapi exposes admin or API interfaces without frame-protection headers, an attacker can embed those endpoints in an invisible iframe and drive user actions via CSS and JavaScript. Adding Hmac Signatures to requests can inadvertently create a false sense of integrity if the signature is computed only over static data and does not prevent the UI from being embedded. An attacker can still load the signed endpoint in an iframe, capture rendered output, and lure the victim into clicking what appears to be a legitimate interface while the signed request is issued in the background.

In Strapi, the admin panel and certain API routes may include query parameters or headers authenticated via Hmac Signatures. If Strapi does not explicitly set Content-Security-Policy: frame-ancestors 'none' (or a restrictive policy), the admin UI or API responses can be framed. Even with Hmac Signatures validating the request origin, clickjacking persists because the signature does not stop the UI from being rendered inside an attacker-controlled page. The user may be tricked into performing an action (e.g., changing settings or publishing content) that carries a valid Hmac Signature, and Strapi processes it as a legitimate, authenticated request.

Consider an endpoint that uses Hmac Signatures to bind a timestamp and a user identifier. If Strapi’s response includes sensitive controls or confirmation messages, an attacker can overlay invisible iframes and position them under mouse coordinates to simulate clicks. The Hmac Signature ensures the request is well-formed, but it does not mitigate the UI deception. This is particularly relevant for operations that change state, such as publishing entries or modifying permissions, where the attacker relies on user interaction within the embedded interface.

To map this to real-world risks, findings from middleBrick’s checks for BOLA/IDOR and Property Authorization can surface endpoints that expose admin functionality with Hmac Signatures but lack frame-ancestor restrictions. middleBrick also runs checks aligned with OWASP API Top 10, identifying missing clickjacking defenses as part of the UI integration surface. The scanner does not fix headers or policies but highlights where authorization controls and signature schemes coexist with exposed interfaces.

Hmac Signatures-Specific Remediation in Strapi — concrete code fixes

Remediation focuses on two layers: preventing embedding of sensitive interfaces and ensuring Hmac Signatures are applied to state-changing operations. Strapi should enforce a strict Content-Security-Policy header for admin routes and API responses, and Hmac Signatures must cover dynamic values tied to the action being performed. Below are concrete examples demonstrating both header configuration and signature generation in Strapi custom middleware.

1. Set Content-Security-Policy to prevent framing

In Strapi, you can add middleware to set security headers for all responses. This policy disallows framing by any ancestor and enforces strict transport security for admin panels.

// In strapi/config/middleware.js
module.exports = {
  settings: {
    middlewares: [
      {
        name: 'security-headers',
        config: {
          secureHeaders: {
            contentSecurityPolicy: {
              useDefaults: false,
              directives: {
                "default-src": ["'self'"],
                "script-src": ["'self'", "'unsafe-inline'"],
                "style-src": ["'self'", "'unsafe-inline'"],
                "img-src": ["'self'", "data:"],
                "connect-src": ["'self'"],
                "frame-ancestors": ["'none'"],
                "base-uri": ["'self'"],
                "form-action": ["'self'"],
              },
            },
            // Ensure admin pages are not embedded
            xFrameOptions: 'DENY',
            // Enforce HTTPS in production-like environments
            strictTransportSecurity: 'max-age=63072000; includeSubDomains; preload',
          },
        },
      },
    ],
  },
};

2. Hmac Signature generation for sensitive actions

When building custom endpoints or extending Strapi controllers, compute an Hmac Signature over a combination of user identifier, timestamp, action, and resource ID. Validate the signature server-side before performing state changes. Use Node.js crypto module to create and verify signatures.

// Example: Generate Hmac Signature in a Strapi controller
const crypto = require('crypto');

const SECRET = process.env.HMAC_SECRET; // Store securely, e.g., in environment variables

function generateHmac(payload) {
  const message = `${payload.userId}|${payload.timestamp}|${payload.action}|${payload.resourceId}`;
  return crypto.createHmac('sha256', SECRET).update(message).digest('hex');
}

// In a controller action
async updateEntity(ctx) {
  const { userId, timestamp, action, resourceId, entityId } = ctx.request.body;
  const receivedSig = ctx.request.headers['x-hmac-signature'];
  if (!receivedSig) {
    return ctx.badRequest('Missing signature');
  }
  const expectedSig = generateHmac({ userId, timestamp, action, resourceId });
  // Use timing-safe compare to avoid timing attacks
  const isValid = crypto.timingSafeEqual(
    Buffer.from(receivedSig, 'hex'),
    Buffer.from(expectedSig, 'hex')
  );
  if (!isValid) {
    return ctx.unauthorized('Invalid signature');
  }
  // Proceed only if the timestamp is recent (e.g., within 5 minutes)
  const now = Date.now();
  if (Math.abs(now - Number(timestamp)) > 5 * 60 * 1000) {
    return ctx.badRequest('Stale request');
  }
  // Perform the state-changing operation
  const updated = await strapi.entityService.update('api::resource.resource', entityId, {
    data: ctx.request.body,
  });
  return updated;
}

3. Validate and verify incoming Hmac Signatures in middleware

For API routes that rely on Hmac Signatures, add a lightweight middleware that checks the signature before routing to the handler. This ensures that only properly signed requests can trigger sensitive operations.

// In strapi/config/middleware.js — add a custom middleware
const crypto = require('crypto');

const SECRET = process.env.HMAC_SECRET;

module.exports = {
  settings: {
    middlewares: [
      {
        name: 'hmac-validator',
        config: {
          paths: ['/api/resources/*/actions/update'], // customize as needed
          async handler(ctx, next) {
            if (ctx.method !== 'POST' && ctx.method !== 'PUT' && ctx.method !== 'PATCH') {
              return next();
            }
            const receivedSig = ctx.request.headers['x-hmac-signature'];
            if (!receivedSig) {
              return ctx.throw(401, 'Missing signature');
            }
            const { userId, timestamp, action, resourceId } = ctx.request.body;
            const message = `${userId}|${timestamp}|${action}|${resourceId}`;
            const expectedSig = crypto.createHmac('sha256', SECRET).update(message).digest('hex');
            const valid = crypto.timingSafeEqual(
              Buffer.from(receivedSig, 'hex'),
              Buffer.from(expectedSig, 'hex')
            );
            if (!valid) {
              return ctx.throw(401, 'Invalid signature');
            }
            return next();
          },
        },
      },
    ],
  },
};

These examples demonstrate how Hmac Signatures complement, but do not replace, server-side security controls. Always pair signatures with frame-ancestor policies and strict validation of inputs to reduce the impact of clickjacking and other UI-level attacks.

Frequently Asked Questions

Can Hmac Signatures alone prevent clickjacking in Strapi?
No. Hmac Signatures protect the integrity of requests but do not prevent an attacker from embedding Strapi interfaces inside iframes. You must also set Content-Security-Policy frame-ancestors and X-Frame-Options to block embedding.
What additional checks does middleBucket provide related to this risk?
middleBrick scans for missing frame-ancestor restrictions and authorization gaps via BOLA/IDOR and Property Authorization checks, surfacing endpoints that may be exposed to clickjacking when combined with Hmac Signatures.