campaign_connector/docs/security/api-security.md
admin 30c2cfeba5 feat(security): Implement comprehensive security fixes and enhancements
- Added Security Handoff Report detailing resolved issues and current configurations.
- Implemented CSRF protection using Flask-WTF, including token management in templates and JavaScript.
- Created standardized error handling module to log detailed errors while returning generic messages.
- Developed phone number validation module to ensure compliance with E.164 standards.
- Added CSV injection prevention measures during file uploads.
- Updated installation guide for clarity and completeness.
- Created script to update API keys from Android device, ensuring secure key management.
- Enhanced Docker security configurations to remove privileged mode and host networking.
- Implemented logging and sanitization for error messages to prevent information disclosure.
- Added verification script to test security setup flow and validate configurations.
2026-01-01 17:18:50 -07:00

4.5 KiB

API Security

This document covers the API authentication implementation in SMS Campaign Manager.

Authentication System

All API endpoints require authentication via one of:

  • X-API-Key header: X-API-Key: YOUR_KEY
  • Bearer token: Authorization: Bearer YOUR_KEY
  • Session cookie: From web login

API Key Types

Key Variable Access Level
Admin ADMIN_API_KEY Full access including database reset
User USER_API_KEY Standard operations
Termux TERMUX_API_KEY Android device communication

Admin Key

Use for administrative operations:

  • All user permissions
  • /api/database/reset - Database reset
  • System configuration changes

User Key

Use for standard operations:

  • Campaign management
  • SMS sending
  • CSV upload
  • Analytics viewing

Termux Key

Use for Android communication:

  • Internal server-to-device requests
  • SMS sending via Termux API
  • Device status queries

Protected Endpoints

Campaign Routes

All require User role minimum:

  • POST /api/campaign/create
  • POST /api/campaign/start
  • POST /api/campaign/pause
  • POST /api/campaign/resume
  • GET /api/campaign/status
  • GET /api/campaign/list

SMS Routes

All require User role minimum:

  • POST /api/sms/send/enhanced
  • POST /api/sms/test
  • GET /api/sms/status

Upload Routes

All require User role minimum:

  • POST /api/csv/upload
  • POST /api/campaign/upload

Database Routes

  • GET /api/database/stats - User role
  • POST /api/database/reset - Admin role only

Android Termux API

Protected endpoints on Android:

  • POST /api/sms/send
  • POST /api/sms/send-reply

Security Features

Key Hashing

API keys are hashed with SHA-256 before comparison. Keys are never stored in plaintext.

Constant-Time Comparison

All key comparisons use constant-time algorithms to prevent timing attacks.

Role-Based Access

Each endpoint declares required role level:

@require_auth(role='admin')  # Admin only
@require_auth(role='user')   # User or Admin

Generating Keys

Generate new API keys:

python3 src/core/auth.py

This generates cryptographically secure 64-character hex strings.

Using API Keys

curl Examples

# X-API-Key header
curl -H "X-API-Key: YOUR_KEY" http://localhost:5000/api/campaign/list

# Bearer token
curl -H "Authorization: Bearer YOUR_KEY" http://localhost:5000/api/campaign/list

# POST with data
curl -X POST \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phone":"+1234567890","message":"Hello"}' \
  http://localhost:5000/api/sms/send/enhanced

Python Example

import requests

API_KEY = "your-api-key-here"
BASE_URL = "http://localhost:5000"

headers = {
    "X-API-Key": API_KEY,
    "Content-Type": "application/json"
}

# List campaigns
response = requests.get(f"{BASE_URL}/api/campaign/list", headers=headers)
print(response.json())

# Send SMS
data = {"phone": "+1234567890", "message": "Test"}
response = requests.post(f"{BASE_URL}/api/sms/send/enhanced", headers=headers, json=data)
print(response.json())

Error Responses

401 Unauthorized

No API key or invalid key:

{
  "error": "Authentication required",
  "message": "Please provide valid API key"
}

403 Forbidden

Valid key but insufficient permissions:

{
  "error": "Insufficient permissions",
  "message": "Admin role required"
}

Best Practices

Required

  • Generate unique random keys
  • Store keys in .env file only
  • Set file permissions: chmod 600 .env
  • Never commit keys to version control
  • Rotate keys every 90 days
  • Use different keys per environment
  • Monitor failed authentication logs
  • Use HTTPS in production (Tailscale provides this)

Troubleshooting

Invalid API Key

# Verify key is set in container
docker compose exec sms-campaign env | grep API_KEY

# Check .env format (no spaces around =)
cat .env | grep API_KEY

# Restart to reload
docker compose restart

Permission Denied

Using wrong key type for endpoint:

  • User key for admin endpoints returns 403
  • Check endpoint requires admin role
  • Use admin key for privileged operations