HIGH api key exposurestrapifirestore

Api Key Exposure in Strapi with Firestore

Api Key Exposure in Strapi with Firestore — how this specific combination creates or exposes the vulnerability

Strapi is a headless CMS that can be configured to use Google Cloud Firestore as a data store or as an integration endpoint. When developers configure external services or frontend applications to call Strapi controllers, they often embed a Firestore service account key or an API key within the Strapi project settings or environment files. If these credentials are accidentally committed to a public repository, logged in error messages, or exposed through an overly permissive CORS or endpoint configuration, an attacker can harvest the key.

Firestore API keys (often confused with service account keys) are intended to identify the project for REST and gRPC traffic, but by themselves they do not enforce user-level permissions. In a Strapi deployment, a key with broad access that is exposed publicly enables unauthenticated enumeration or modification of Firestore data if the security rules are misconfigured. Because middleBrick performs black-box scanning without credentials, it can detect exposed keys in responses, OpenAPI specs, and runtime behavior, and flag the risk under Data Exposure and Unsafe Consumption checks.

The combination increases impact because Strapi may expose administrative endpoints that return configuration or logs containing the key, while Firestore rules that rely only for API key validation (instead of authenticated UID-based checks) may permit read or write access. An attacker can use the key to interact directly with Firestore outside of Strapi, bypassing business logic and rate limits enforced by the CMS. middleBrick’s LLM/AI Security checks look for key patterns in model outputs and system prompts, while the Data Exposure and Property Authorization checks test whether unauthenticated access to endpoints can lead to unauthorized data retrieval or privilege escalation.

During a scan, middleBrick tests the unauthenticated attack surface of the Strapi instance, including any configured Firestore routes. It checks whether API keys appear in responses, whether OpenAPI specs inadvertently document credentials, and whether endpoints allow excessive agency through function-like calls or unsafe consumption patterns. The scanner maps findings to frameworks such as OWASP API Top 10 and provides prioritized findings with severity and remediation guidance, but it does not fix or block the exposed key.

Firestore-Specific Remediation in Strapi — concrete code fixes

To reduce the risk of key exposure, keep service account keys and API keys out of the Strapi codebase and runtime responses. Use environment variables injected securely at deployment, avoid echoing configuration in logs, and enforce least-privilege Firestore security rules.

Principle of least privilege with Firestore rules

Define Firestore rules that require authentication and scope access to user-specific documents. Do not rely on API keys alone for authorization. The following example allows read/write only within a user’s own subcollection:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
      // Restrict access to user-specific subcollection
      match /messages/{messageId} {
        allow read, write: if request.auth != null && request.auth.uid == userId;
      }
    }
  }
}

Securely accessing Firestore from Strapi controllers

Use a service account key stored as an environment variable and initialize the Admin SDK only when necessary. Avoid returning the key or raw configuration in API responses.

// strapi/services/firestore.js
const { initializeApp, cert } = require('firebase-admin/app');
const { getFirestore } = require('firebase-admin/firestore');

let app;
if (!initializeApp.apps.length) {
  const serviceAccount = JSON.parse(process.env.FIRESTORE_SERVICE_ACCOUNT_KEY);
  app = initializeApp({
    credential: cert(serviceAccount)
  });
}

const db = getFirestore(app);

module.exports = {
  async getUserDocuments(userId) {
    const snapshot = await db.collection('users').doc(userId).collection('data').get();
    return snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
  },
  async updateUserDocument(userId, data) {
    await db.collection('users').doc(userId).collection('data').doc('profile').set(data);
  }
};

Avoid exposing keys in Strapi responses and logs

Ensure that environment variables such as FIRESTORE_SERVICE_ACCOUNT_KEY are not included in JSON serialization, error traces, or health-check outputs. Configure logging to redact sensitive fields, and validate that OpenAPI specs generated by Strapi do not contain literal keys or secrets. middleBrick’s scans can help identify such exposures by analyzing spec consistency and runtime outputs.

Continuous monitoring and CI/CD integration

With the Pro plan, you can enable continuous monitoring so that Strapi deployments are rescanned on a configurable schedule. The GitHub Action can fail a build if a scan detects an API key in responses or an unauthenticated endpoint grants unsafe access to Firestore data. Use the MCP Server to run scans directly from your IDE during development, catching regressions before they reach staging.

Frequently Asked Questions

Can Firestore API keys alone grant access to data in Strapi?
API keys identify the project for traffic but do not enforce user-level permissions. Access depends on Firestore security rules; keys alone typically cannot read or write data if rules require authentication. Exposed keys should still be treated as high risk because they may enable unauthenticated enumeration or abuse if rules are misconfigured.
How does middleBrick detect exposed API keys in Strapi deployments?
middleBrick runs unauthenticated scans that inspect responses, OpenAPI/Swagger specs (including resolved $ref definitions), and runtime behavior for patterns resembling API keys or service account credentials. It checks Data Exposure, Property Authorization, and LLM/AI Security checks to surface potential leaks without making any changes to the system.