Yaltopia-Ticket-Email/docs/SECURITY.md

6.5 KiB

Security & Architecture Improvements

🔒 Current Security Issues

1. API Key Exposure in Frontend

Issue: EmailSender component stores API key in browser state

// CURRENT - INSECURE
const [apiKey, setApiKey] = useState('') // Exposed in browser

Fix: Remove frontend API key input entirely

// RECOMMENDED - Remove EmailSender from production
// Only use for development testing

2. Missing Input Validation

Issue: No validation for email addresses, URLs, or data inputs

// CURRENT - NO VALIDATION
const handleSendEmail = async () => {
  // Direct use without validation
}

Fix: Add proper validation

// RECOMMENDED
import { z } from 'zod'

const emailSchema = z.object({
  to: z.string().email(),
  eventName: z.string().min(1).max(200),
  ctaUrl: z.string().url()
})

const validateInput = (data: unknown) => {
  return emailSchema.parse(data)
}

3. Missing Rate Limiting

Issue: No protection against email spam/abuse

// CURRENT - NO RATE LIMITING
await resend.emails.send(payload)

Fix: Implement rate limiting

// RECOMMENDED
import rateLimit from 'express-rate-limit'

const emailLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 10, // limit each IP to 10 emails per windowMs
  message: 'Too many emails sent, please try again later'
})

app.use('/api/send-email', emailLimiter)

4. Missing Environment Variables

Issue: No .env file or environment configuration

# MISSING
RESEND_API_KEY=
FROM_DOMAIN=
RATE_LIMIT_MAX=

Fix: Add environment configuration

# .env
RESEND_API_KEY=re_your_key_here
FROM_DOMAIN=yourdomain.com
RATE_LIMIT_MAX=10
RATE_LIMIT_WINDOW_MS=900000

5. Missing Content Security Policy

Issue: No CSP headers for XSS protection

// RECOMMENDED - Add to backend
app.use((req, res, next) => {
  res.setHeader('Content-Security-Policy', 
    "default-src 'self'; script-src 'none'; object-src 'none';"
  )
  next()
})

🏗️ Architecture Improvements

1. Add Environment Configuration

// config/email.ts
export const emailConfig = {
  resend: {
    apiKey: process.env.RESEND_API_KEY!,
    fromDomain: process.env.FROM_DOMAIN!,
  },
  rateLimit: {
    max: parseInt(process.env.RATE_LIMIT_MAX || '10'),
    windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS || '900000'),
  }
}

2. Add Input Validation Layer

// lib/validation.ts
import { z } from 'zod'

export const invitationSchema = z.object({
  to: z.string().email(),
  eventName: z.string().min(1).max(200),
  dateTime: z.string().min(1),
  location: z.string().min(1).max(500),
  ctaUrl: z.string().url(),
})

export const paymentSchema = z.object({
  to: z.string().email(),
  amount: z.number().positive(),
  currency: z.enum(['USD', 'EUR', 'GBP']),
  description: z.string().min(1).max(500),
})

3. Add Logging & Monitoring

// lib/logger.ts
export const logger = {
  info: (message: string, meta?: any) => {
    console.log(JSON.stringify({ level: 'info', message, meta, timestamp: new Date() }))
  },
  error: (message: string, error?: any) => {
    console.error(JSON.stringify({ level: 'error', message, error: error?.message, timestamp: new Date() }))
  }
}

// Usage in ResendService
async sendEmail(...) {
  try {
    logger.info('Sending email', { templateId, to })
    const result = await this.resend.emails.send(payload)
    logger.info('Email sent successfully', { messageId: result.data?.id })
    return result
  } catch (error) {
    logger.error('Failed to send email', error)
    throw error
  }
}

4. Add Error Handling Middleware

// middleware/errorHandler.ts
export const errorHandler = (err: Error, req: Request, res: Response, next: NextFunction) => {
  logger.error('Unhandled error', err)
  
  if (err.name === 'ValidationError') {
    return res.status(400).json({ error: 'Invalid input data' })
  }
  
  if (err.message.includes('Resend')) {
    return res.status(503).json({ error: 'Email service temporarily unavailable' })
  }
  
  res.status(500).json({ error: 'Internal server error' })
}

🛡️ Production Security Checklist

Backend Security

  • Remove EmailSender component from production build
  • Add input validation with Zod or similar
  • Implement rate limiting
  • Add proper error handling
  • Use environment variables for all secrets
  • Add request logging
  • Implement CORS properly
  • Add Content Security Policy headers
  • Validate email addresses before sending
  • Sanitize all user inputs

Email Security

  • Validate all URLs before including in emails
  • Use only verified domains for sending
  • Implement unsubscribe links where required
  • Add SPF, DKIM, DMARC records
  • Monitor bounce rates and spam reports
  • Implement email delivery tracking

Infrastructure Security

  • Use HTTPS only
  • Implement proper authentication
  • Add API key rotation
  • Monitor API usage
  • Set up alerts for unusual activity
  • Regular security audits
backend/
├── src/
│   ├── config/
│   │   ├── email.ts          # Email configuration
│   │   └── security.ts       # Security settings
│   ├── middleware/
│   │   ├── auth.ts           # Authentication
│   │   ├── rateLimit.ts      # Rate limiting
│   │   └── validation.ts     # Input validation
│   ├── services/
│   │   ├── emailService.ts   # Email sending logic
│   │   └── templateService.ts # Template management
│   ├── templates/            # Email templates (copied from playground)
│   ├── utils/
│   │   ├── logger.ts         # Logging utility
│   │   └── validator.ts      # Validation schemas
│   └── routes/
│       └── emails.ts         # Email API routes
├── .env                      # Environment variables
├── .env.example             # Environment template
└── package.json

🚀 Implementation Priority

  1. High Priority (Security Critical)

    • Remove API key from frontend
    • Add input validation
    • Implement rate limiting
    • Add environment variables
  2. Medium Priority (Best Practices)

    • Add proper error handling
    • Implement logging
    • Add CORS configuration
    • Content Security Policy
  3. Low Priority (Nice to Have)

    • Email delivery tracking
    • Advanced monitoring
    • Performance optimization
    • A/B testing framework