Skip to content

🔐 Fix: Admin Password Exposed in Client-Side Bundle#36

Open
Pranavms09 wants to merge 3 commits into
JhaSourav07:mainfrom
Pranavms09:fix/admin-auth-firebase
Open

🔐 Fix: Admin Password Exposed in Client-Side Bundle#36
Pranavms09 wants to merge 3 commits into
JhaSourav07:mainfrom
Pranavms09:fix/admin-auth-firebase

Conversation

@Pranavms09
Copy link
Copy Markdown

🔐 Fix: Admin Password Exposed in Client-Side Bundle

Closes #28


📋 Summary

This PR fixes a critical security vulnerability where the admin password was stored in a VITE_ environment variable and shipped inside the client-side JavaScript bundle — making it readable by anyone via browser DevTools.

The client-side password check has been fully replaced with Firebase Authentication (email/password sign-in), and Firestore security rules have been added to restrict access to the feedback collection.


🐛 Problem

The admin password was read directly from import.meta.env.VITE_ADMIN_PASSWORD:

// BEFORE (vulnerable)
const ADMIN_PASSWORD = import.meta.env.VITE_ADMIN_PASSWORD;
if (pw === ADMIN_PASSWORD) { onAuth(); }

Since all VITE_ variables are embedded into the JS bundle at build time, the password was fully visible in DevTools → Sources to any user.


✅ Solution

Replaced the password check with Firebase Auth:

// AFTER (secure)
import { signInWithEmailAndPassword, onAuthStateChanged } from "firebase/auth";

await signInWithEmailAndPassword(auth, email, password);

Auth state is now managed by onAuthStateChanged — session persists on refresh without sessionStorage hacks.


📁 Files Changed

File Change
src/pages/Admin/Admin.jsx Replaced password logic with Firebase Auth
src/lib/firebase.js Added and exported auth instance
firestore.rules Created — restricts feedback access to admin UID only
.env.example Removed VITE_ADMIN_PASSWORD, added setup instructions

🔒 Firestore Security Rules

A firestore.rules file has been included in the root of the repo for your review. Key rules:

  • /feedback collection → readable/writable only by the verified admin UID
  • /users/{userId} → readable/writable only by the matching authenticated user
  • All other paths → denied by default

⚠️ Note for maintainer: Please replace ADMIN_UID_PLACEHOLDER in firestore.rules with your actual Admin UID before deploying to production.


🧪 Testing Done

  • App builds without errors (npm run build)
  • Admin login works with Firebase email/password
  • Wrong password correctly shows an error
  • Sign out works and returns to login screen
  • Page refresh keeps the admin logged in (onAuthStateChanged)
  • VITE_ADMIN_PASSWORD removed from all files
  • Built JS bundle contains no password string
  • Tested on personal Firebase project (as per maintainer instructions)

🚀 Deployment Notes (For Maintainer)

As discussed, I have tested this on my own personal Firebase project. For production:

  1. Replace ADMIN_UID_PLACEHOLDER in firestore.rules with your real Admin UID
  2. Apply firestore.rules to the production Firebase project
  3. Create the admin user in Firebase Console → Authentication
  4. Remove VITE_ADMIN_PASSWORD from production environment variables
  5. No other environment variables need to change

🔗 Related

Closes #28

- Remove VITE_ADMIN_PASSWORD from Admin.jsx and .env
- Implement signInWithEmailAndPassword for admin login
- Use onAuthStateChanged for persistent auth state
- Add firestore.rules with role-based access control
- Update .env.example to remove deprecated variable

Fixes #security-vulnerability
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Apr 19, 2026

@Pranavms09 is attempting to deploy a commit to the jhasourav07's projects Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes an insecure client-side admin password check (previously bundled via a VITE_ env var) and replaces Admin access with Firebase Authentication, alongside repository config/docs updates intended to support the new auth model and Firestore protection.

Changes:

  • Replace Admin Panel password comparison with Firebase Auth email/password sign-in and persisted auth state.
  • Export a Firebase auth instance from the shared Firebase initializer.
  • Add Firestore security rules and update environment/documentation/gitignore to remove VITE_ADMIN_PASSWORD.

Reviewed changes

Copilot reviewed 5 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/pages/Admin/Admin.jsx Swaps client-side password gate for Firebase Auth + auth-state-driven UI.
src/lib/firebase.js Adds and exports auth via getAuth(app).
firestore.rules Introduces Firestore rules intended to restrict access (needs alignment with existing app behavior).
CONTRIBUTING.md Updates setup notes to reflect Firebase Auth-based admin access.
.gitignore Ignores .env files while allowing .env.example to be committed.
.env.example Provides Firebase config placeholders; removes admin password guidance.
package-lock.json Lockfile updated as part of dependency graph changes.
Comments suppressed due to low confidence (1)

src/pages/Admin/Admin.jsx:198

  • onSnapshot is registered without an error callback. If Firestore rejects the listener (e.g., permission-denied due to rules/UID mismatch), loading never flips to false and the UI will spin indefinitely. Add an error handler to set loading false and surface a user-visible message (and possibly sign out) when snapshot subscription fails.
    const q = query(collection(db, "feedback"), orderBy("createdAt", sortOrder));
    const unsub = onSnapshot(q, snap => {
      setItems(snap.docs.map(d => ({ id: d.id, ...d.data() })));
      setLoading(false);
    });

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread firestore.rules
Comment on lines +11 to +14
// Users collection — only the owner can read their own doc
match /users/{userId} {
allow read, write: if request.auth != null
&& request.auth.uid == userId;
Comment thread src/pages/Admin/Admin.jsx
setAuthLoading(false);
});
return unsub;
}, []);
Comment thread src/pages/Admin/Admin.jsx
Comment on lines +47 to +51
await signInWithEmailAndPassword(auth, email, pw);
} catch (err) {
setErr(true);
setTimeout(() => setErr(false), 3000);
} finally {
Comment thread src/pages/Admin/Admin.jsx
setLoading(false);
});
return unsub;
}, [authed, sortOrder]);
Comment thread firestore.rules Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🔐 Security: Admin Password Exposed in Client-Side Bundle

2 participants