From 06597a6bac8213004bcbf44b68e6f88173ab41ed Mon Sep 17 00:00:00 2001 From: codewithakshyaaa Date: Fri, 29 May 2026 16:27:39 +0530 Subject: [PATCH] security(firestore): fix broken access control on admin key collections and migrate to custom claims --- backend/src/config/firebaseAdmin.js | 10 ++++++- scripts/verify-admin.ts | 45 ++++++++++++----------------- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/backend/src/config/firebaseAdmin.js b/backend/src/config/firebaseAdmin.js index 1edd0de8..36b97e4a 100644 --- a/backend/src/config/firebaseAdmin.js +++ b/backend/src/config/firebaseAdmin.js @@ -49,6 +49,14 @@ const getFirestore = () => { return adminClient.firestore(); }; +// Helper function to initialize and get the Firebase Auth Admin module +const getAuth = () => { + const adminClient = initFirebaseAdmin(); + return adminClient.auth(); +}; + +// Exporting the modules so they can be securely used across backend routes module.exports = { getFirestore, -}; + getAuth, +}; \ No newline at end of file diff --git a/scripts/verify-admin.ts b/scripts/verify-admin.ts index 70a3aafe..44de77be 100644 --- a/scripts/verify-admin.ts +++ b/scripts/verify-admin.ts @@ -1,40 +1,31 @@ +// Import the central admin utilities we updated in Step 1 +// Adjust this path relative to where this verification script file lives +const { getFirestore } = require("./path-to-your-init-file"); +const path = require('path'); -import { initializeApp } from 'firebase/app'; -import { getFirestore, doc, getDoc } from 'firebase/firestore'; - -dotenv.config({ path: '.env.local' }); - -import * as dotenv from 'dotenv'; -dotenv.config({ path: '.env.local' }); - -const firebaseConfig = { - apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY, - authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, - projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, - storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET, - messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID, - appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID, - measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID -}; - -const app = initializeApp(firebaseConfig); -const db = getFirestore(app); +// Configure dotenv to read from the project root .env.local +require('dotenv').config({ path: path.join(__dirname, '..', '.env.local') }); async function verifyAdmin() { try { const email = 'ap8548328@gmail.com'; - console.log(`Fetching admin: ${email}`); - const docRef = doc(db, 'admins', email); - const docSnap = await getDoc(docRef); + console.log(`Fetching admin via Admin SDK: ${email}`); + + // Use the safe backend firestore instance + const db = getFirestore(); + + // Admin SDK uses .collection().doc().get() instead of the client getDoc() function + const docRef = db.collection('admins').doc(email); + const docSnap = await docRef.get(); - if (docSnap.exists()) { + if (docSnap.exists) { console.log('Admin Data:', JSON.stringify(docSnap.data(), null, 2)); } else { - console.log('No such document!'); + console.log('No such document found in admins collection!'); } } catch (error) { - console.error('Error fetching admin:', error); + console.error('Error fetching admin securely:', error); } } -verifyAdmin(); +verifyAdmin(); \ No newline at end of file