HIGH clickjackingsailsapi keys

Clickjacking in Sails with Api Keys

Clickjacking in Sails with Api Keys — how this specific combination creates or exposes the vulnerability

Clickjacking is a client-side attack that tricks a user into interacting with a hidden or disguised UI element, often by loading the target application in an invisible iframe. In Sails.js applications that rely on API keys for authentication, combining weak framing controls with key-based authorization can expose sensitive actions to clickjacking. When an endpoint is reachable without additional session checks and is embedded in third‑party pages, an attacker can overlay invisible buttons or links that cause the victim’s browser to make unintended requests authenticated with the user’s stored API keys.

Consider a Sails API that returns sensitive data or performs state changes and is documented in an OpenAPI spec generated by middleBrick. If the response includes an API key or the client embeds that key in headers from local storage, and the endpoint is not protected by anti‑clickjacking headers (e.g., X-Frame-Options or Content-Security-Policy: frame-ancestors), an attacker can host a page that embeds <iframe src="https://api.example.com/v1/transfer"></iframe>. Even though the request includes the key, the browser sends it automatically via cookies or headers if the key is tied to session cookies or local storage tokens, leading to unauthorized transfers or data access.

middleBrick’s scans detect missing frame‑ancestor controls and report findings aligned with OWASP API Top 10 and related compliance frameworks. The tool checks whether responses include appropriate CSP frame rules and whether endpoints that accept API keys are reachable in an unauthenticated context that could be abused via framing. Because Sails applications often expose REST endpoints that accept keys as headers, the risk is elevated when developers assume the key alone prevents CSRF or clickjacking without enforcing frame restrictions.

Api Keys-Specific Remediation in Sails — concrete code fixes

Remediation focuses on two layers: preventing framing of sensitive endpoints and ensuring API keys are not usable in a way that invites clickjacking abuse. On the server side, enforce frame‑ancestor policies and avoid storing keys where they are automatically sent with cross‑origin requests. Below are concrete Sails code examples that implement these protections.

1. Set CSP frame-ancestors in Sails policies

Create or update a Sails policy to add Content-Security-Policy headers with frame-ancestors restricted to trusted origins. Apply this policy to routes that validate API keys.

// api/policies/csp-frame-policy.js
module.exports.cspFramePolicy = function (req, res, next) {
  res.set({
    'Content-Security-Policy': "frame-ancestors 'self' https://trusted.example.com;"
  });
  return next();
};

Then apply the policy in config/policies.js:

module.exports.policies = {
  TransferController: {
    '*': ['cspFramePolicy', 'keyAuth']
  }
};

2. Require same-site cookies and secure headers for key storage

If API keys are stored in cookies, mark them as HttpOnly, Secure, and SameSite=Strict. In Sails, configure session/cookie settings in config/session.js:

module.exports.session = {
  adapter: 'sails-mongo',
  cookie: {
    httpOnly: true,
    secure: true,
    sameSite: 'strict',
    maxAge: 24 * 60 * 60 * 1000
  },
  secret: process.env.SESSION_SECRET
};

3. Validate origin header for key-bound requests

For endpoints that use custom API key headers (not cookies), add a check that the Origin or Referer header matches an expected domain. This is not a complete anti‑clickjacking control but adds defense in depth when combined with CSP.

// api/policies/keyAuthAndOrigin.js
module.exports.keyAuthAndOrigin = function (req, res, next) {
  const allowedOrigin = 'https://app.example.com';
  const origin = req.headers.origin;
  const apiKey = req.headers['x-api-key'];

  if (!apiKey || origin !== allowedOrigin) {
    return res.unauthorized('Invalid key or origin');
  }

  // Optionally validate against a registry of valid keys stored in config
  const validKeys = new Set([process.env.API_KEY_1, process.env.API_KEY_2]);
  if (!validKeys.has(apiKey)) {
    return res.unauthorized('Invalid API key');
  }

  return next();
};

Apply this policy to sensitive actions in config/policies.js:

module.exports.policies = {
  PaymentController: {
    charge: ['keyAuthAndOrigin']
  }
};

4. Avoid embedding API keys in client‑side JavaScript

Do not store API keys in local storage or global JavaScript variables that can be read via cross‑origin scripts. Instead, use short‑lived tokens issued after a verified login flow, and keep key validation server‑side using the policies above.

Frequently Asked Questions

Does middleBrick test for clickjacking vulnerabilities in API endpoints that use API keys?
Yes. middleBrick’s security checks include framing controls and header analysis. It reports missing X-Frame-Options or weak Content-Security-Policy frame-ancestors and highlights endpoints that expose keys in a way that could be abused via clickjacking.
Can the middleBrick CLI or GitHub Action enforce remediation for clickjacking risks in Sails APIs?
middleBrick detects and reports findings with severity and remediation guidance. It does not automatically apply fixes. Use the CLI to integrate scans into scripts and the GitHub Action to fail builds when risk scores fall below your chosen threshold, then apply the CSP and key-handling fixes shown above.