MEDIUM clickjackingsailsfirestore

Clickjacking in Sails with Firestore

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

Clickjacking is a client-side UI redress attack where an attacker tricks a user into clicking or interacting with a transparent or disguised element inside an embedded frame. In a Sails application that uses Cloud Firestore as a backend, the risk arises when views render dynamic data without enforcing frame-busting or Content Security Policy (CSP) rules, and when Firestore data is exposed via endpoints that do not validate the request origin.

Sails does not set anti-clickjacking headers by default. If a controller action streams Firestore documents to a view using a client-side embed (e.g., an iframe) or renders a page that includes external widgets, an attacker can host a malicious page that overlays invisible controls on top of authenticated UI elements. Because Firestore security rules typically enforce read/write at the document level and do not inherently consider the embedding context, a compromised UI can trigger unintended Firestore reads or writes via forged requests initiated from the embedded context.

Consider a Sails route that exposes a Firestore document by ID without verifying the request’s referer or origin. An attacker can load this route inside an iframe, hide it, and simulate clicks by positioning interactive elements (buttons, links) over the iframe. If the page contains logic that directly uses Firestore client-side SDK with user credentials, a signed-in user may inadvertently invoke operations (e.g., updating permissions or triggering Cloud Functions) that appear to be benign navigation.

Because middleBrick tests unauthenticated attack surfaces and checks Security Misconfiguration and Input Validation across 12 parallel checks, it can surface exposed endpoints that may contribute to clickjacking risk when combined with UI embedding issues. For example, a misconfigured CORS or missing X-Frame-Options header may be flagged alongside overly permissive Firestore rules that allow read access based only on document ID without considering request origin.

In a real assessment, middleBrick’s OpenAPI/Swagger analysis resolves $ref definitions and cross-references runtime behavior with spec definitions, which can highlight routes that return sensitive Firestore data without framing protections. This does not constitute a fix, but it provides findings with severity and remediation guidance to help developers address the UI and server-side configuration that together enable clickjacking in a Firestore-integrated Sails app.

Firestore-Specific Remediation in Sails — concrete code fixes

Remediation focuses on two layers: server-side HTTP headers and client-side UI controls, while keeping Firestore security rules intact. In Sails, you can set CSP and anti-frame headers in policies or hooks, and adjust frontend templates to prevent embedding attacks.

1. Set anti-clickjacking headers via a policy

Create a policy that adds X-Frame-Options and Content-Security-Policy frame-ancestors rules. Apply this policy to routes that render views or serve API responses consumed by browsers.

// api/policies/csp-frame.js
module.exports = function cspFrame(req, res, next) {
  res.set('X-Frame-Options', 'DENY');
  res.set('Content-Security-Policy', "frame-ancestors 'none'");
  return next();
};

Then register the policy in config/policies.js and attach it to relevant controllers or actions.

2. Tighten Firestore read rules by request origin

Firestore security rules cannot inspect HTTP referers directly, so move origin validation to your Sails backend. Create an endpoint that checks the request origin and conditionally returns document references or tokens needed by the client-side SDK.

// api/controllers/FirestoreController.js
const { initializeApp } = require('firebase-admin/app');
const { getFirestore } = require('firebase-admin/firestore');

module.exports = {
  getDocument: async function(req, res) {
    const allowedOrigin = process.env.ALLOWED_ORIGIN || 'https://yourdomain.com';
    const requestOrigin = req.headers.origin || req.headers.referer || '';
    if (!requestOrigin.startsWith(allowedOrigin)) {
      return res.forbidden({ error: 'Invalid origin' });
    }

    initializeApp();
    const db = getFirestore();
    const doc = await db.collection('items').doc(req.param('id')).get();
    if (!doc.exists) {
      return res.notFound();
    }
    return res.ok(doc.data());
  }
};

This ensures that only requests with an expected origin can retrieve Firestore data, reducing the attack surface for clickjacking-induced reads.

3. Avoid embedding sensitive UI in iframes

In your Sails views (e.g., EJS), avoid rendering pages inside iframes when they rely on authenticated Firestore access. If embedding is required, use CSP frame-ancestors to restrict parents and add sandbox attributes with strict allowlist.

<!-- views/page.ejs -->
<iframe src="/internal/widget" sandbox="allow-scripts allow-same-origin"></iframe>

Combine this with the CSP policy above to enforce that the page cannot be embedded by external sites.

4. Use CSRF tokens for state-changing operations

Even with headers and origin checks, ensure that mutating Firestore writes require CSRF protection. Sails has built-in CSRF protection for views; ensure it is enabled and applied to forms that trigger Firestore updates via the backend.

<!-- In a form -->
<input type="hidden" name="_csrf" value="<%= _csrf %>">

This prevents unauthorized commands from being executed when a user is tricked into interacting with a disguised UI element.

5. Validate and sanitize all inputs

Use Sails’ built-in validation and sanitizers to ensure that Firestore document IDs and query parameters are strictly formatted, preventing injection-style UI abuse that could be leveraged alongside clickjacking vectors.

Frequently Asked Questions

Does middleBrick test for clickjacking risks in Sails applications using Firestore?
Yes. middleBrick runs a Security Misconfiguration check that inspects HTTP headers such as X-Frame-Options and Content-Security-Policy frame-ancestors, and it cross-references these findings with Firestore access patterns to highlight routes that may contribute to clickjacking when combined with UI embedding issues.
Can Firestore security rules alone prevent clickjacking attacks in Sails?
No. Firestore security rules enforce document-level access but cannot inspect HTTP framing headers or origin context. Clickjacking mitigation requires server-side headers and careful UI design in Sails, complemented by secure Firestore rules.