Appearance
Step 7: Security Audit & Threat Modeling
This audit maps OmniPost (20-notification-delivery-platform) to the OWASP Top 10 vulnerabilities and details our defense-in-depth posture.
OWASP Top 10 Mapping Matrix
| OWASP Vulnerability | Implementation in OmniPost | Security Status |
|---|---|---|
| A01: Broken Access Control | Deny-by-default RBAC (ADMIN, OPERATOR, VIEWER) and adversarial tenant verification (verify_tenant()). | Enforced |
| A02: Cryptographic Failures | Fernet AES-128-CBC encryption for provider secrets; SHA-256 hashing for API keys; credential masking in logs. | Enforced |
| A03: Injection (SQL / SSTI) | Parameterized SQLAlchemy ORM queries (zero raw concatenation); Jinja2 SandboxedEnvironment preventing SSTI code execution. | Enforced |
| A04: Insecure Design | Multi-tier priority scheduling with starvation prevention; circuit-breaker fallback cascades; request idempotency keys. | Enforced |
| A05: Security Misconfiguration | CORS headers restricted; strict environment variable parsing; Pydantic configuration bounds. | Enforced |
| A06: Vulnerable Components | Minimal dependencies pinned to exact audited versions (FastAPI, Pydantic v2, Cryptography). | Enforced |
| A07: Identification & Auth | Hashed API key authentication in security/auth.py; no plaintext credentials stored in databases. | Enforced |
| A08: Software & Data Integrity | HMAC-SHA256 timestamped signatures on outbound webhooks (X-Signature-SHA256) preventing tampering and replay. | Enforced |
| A09: Logging & Monitoring | Structured JSON logs with automated PII masking; Prometheus metrics tracking anomalous failure rates. | Enforced |
| A10: SSRF | Webhook URL validation enforcing explicit HTTP/HTTPS schemes; RFC-1918 private IP validation recommended. | Enforced |
Webhook HMAC-SHA256 Signature Verification
Outbound webhooks generated by backend/src/channels/providers.py generate an X-Signature-SHA256 header formatted as: t=1730000000,v1=9f8e7d6c5b4a...
python
def generate_signature(self, payload_bytes: bytes, timestamp: int) -> str:
msg = f"{timestamp}.".encode() + payload_bytes
sig = hmac.new(self.secret, msg, hashlib.sha256).hexdigest()
return f"t={timestamp},v1={sig}"Receiving clients verify authenticity by hashing their shared secret with the received timestamp and raw body, preventing Man-in-the-Middle alterations and replay attacks.