Files
auditly/SECURITY_MIGRATION.md
2025-08-24 00:48:41 -07:00

5.7 KiB

Security Migration: Frontend to Cloud Functions

Overview

This migration addresses critical security vulnerabilities by moving all Firestore interactions from the frontend to secure cloud functions. This prevents unauthorized data access and protects your database structure from being exposed to users.

Security Issues Addressed

Before (Vulnerable)

  • Direct Firestore access from frontend
  • Database schema exposed to users
  • API keys visible in browser
  • Firestore rules can be analyzed by attackers
  • Users can potentially bypass frontend logic

After (Secure)

  • All data operations go through authenticated cloud functions
  • Database structure hidden from frontend
  • User authorization verified on every request
  • No sensitive data exposed to client
  • Complete audit trail of data access

Migration Changes

1. Cloud Functions (Backend)

File: functions/index.js

Added secure endpoints:

  • getOrgData - Get organization data with auth
  • updateOrgData - Update organization data with auth
  • getEmployees - Get employees with auth
  • getSubmissions - Get submissions with auth
  • getReports - Get reports with auth
  • upsertEmployee - Create/update employees with auth
  • saveReport - Save reports with auth
  • getCompanyReports - Get company reports with auth

Each endpoint:

  • Verifies user authentication
  • Checks user authorization for the organization
  • Validates all inputs
  • Returns appropriate error messages

2. Secure API Service (Frontend)

File: src/services/secureApi.ts

New service that:

  • Handles all communication with cloud functions
  • Provides type-safe methods for data operations
  • Manages authentication tokens
  • Handles errors gracefully

3. Updated Context (Frontend)

File: src/contexts/OrgContext.tsx

Completely rewritten to:

  • Use secure API instead of direct Firestore
  • Load data on component mount instead of real-time listeners
  • Provide loading states for better UX
  • Handle authentication properly

4. Firestore Rules (Security)

File: firestore.rules

Updated rules to:

// DENY ALL direct client access
allow read, write: if false;

Deployment Steps

  1. Deploy Cloud Functions

    cd functions
    npm install
    cd ..
    firebase deploy --only functions
    
  2. Deploy Firestore Rules

    firebase deploy --only firestore:rules
    
  3. Use Deployment Script

    ./deploy-security.sh
    

Frontend Usage

Before (Direct Firestore)

// DON'T DO THIS ANYMORE
import { collection, doc, getDoc } from 'firebase/firestore';
const orgDoc = await getDoc(doc(db, 'orgs', orgId));

After (Secure API)

// DO THIS INSTEAD
import { secureApi } from '../services/secureApi';
const orgData = await secureApi.getOrgData(orgId, userId);

API Methods Available

Organization Data

  • secureApi.getOrgData(orgId, userId)
  • secureApi.updateOrgData(orgId, userId, data)

Employees

  • secureApi.getEmployees(orgId, userId)
  • secureApi.upsertEmployee(orgId, userId, employeeData)

Submissions & Reports

  • secureApi.getSubmissions(orgId, userId)
  • secureApi.getReports(orgId, userId)
  • secureApi.saveReport(orgId, userId, employeeId, reportData)

Company Reports

  • secureApi.getCompanyReports(orgId, userId)
  • secureApi.saveCompanyReport(orgId, report)

Existing API (Already Secure)

  • secureApi.sendOTP(email, inviteCode?)
  • secureApi.verifyOTP(email, otp)
  • secureApi.createInvitation(...)
  • secureApi.generateEmployeeReport(...)
  • secureApi.generateCompanyWiki(...)
  • secureApi.chat(...)

Authentication Flow

  1. User logs in via OTP (cloud function)
  2. Cloud function returns user data and token
  3. Frontend stores user data in AuthContext
  4. All API calls include user ID for authorization
  5. Cloud functions verify user access to organization data

Error Handling

The secure API provides consistent error handling:

try {
  const data = await secureApi.getOrgData(orgId, userId);
  // Handle success
} catch (error) {
  // Handle error - could be auth, network, or data error
  console.error('Failed to load organization:', error.message);
}

Performance Considerations

  • Loading States: UI shows loading while data fetches
  • Caching: Local state caching reduces API calls
  • Batch Operations: Multiple related operations in single calls
  • Error Recovery: Graceful fallbacks for network issues

Security Benefits

  1. Zero Trust: Every request is authenticated and authorized
  2. Data Hiding: Database schema not exposed to frontend
  3. Audit Trail: All access logged in cloud functions
  4. Input Validation: All data validated server-side
  5. Rate Limiting: Can be added to cloud functions
  6. IP Filtering: Can be implemented at cloud function level

Testing

After migration, verify:

  1. Users can only access their organization's data
  2. Unauthenticated requests are rejected
  3. Invalid organization IDs are rejected
  4. All CRUD operations work through secure API
  5. Error messages don't leak sensitive information

Monitoring

Monitor these metrics:

  • API response times
  • Authentication failures
  • Authorization failures
  • Data access patterns
  • Error rates

Future Enhancements

This secure foundation enables:

  • Role-based access control (RBAC)
  • Data encryption at rest
  • Advanced audit logging
  • API rate limiting
  • IP whitelisting
  • Multi-factor authentication

Support

If you encounter issues:

  1. Check browser console for detailed error messages
  2. Verify Firebase project configuration
  3. Ensure cloud functions are deployed successfully
  4. Check Firestore rules are updated

The secure API provides comprehensive error messages to help debug issues during development.