Skip to content

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 VulnerabilityImplementation in OmniPostSecurity Status
A01: Broken Access ControlDeny-by-default RBAC (ADMIN, OPERATOR, VIEWER) and adversarial tenant verification (verify_tenant()).Enforced
A02: Cryptographic FailuresFernet 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 DesignMulti-tier priority scheduling with starvation prevention; circuit-breaker fallback cascades; request idempotency keys.Enforced
A05: Security MisconfigurationCORS headers restricted; strict environment variable parsing; Pydantic configuration bounds.Enforced
A06: Vulnerable ComponentsMinimal dependencies pinned to exact audited versions (FastAPI, Pydantic v2, Cryptography).Enforced
A07: Identification & AuthHashed API key authentication in security/auth.py; no plaintext credentials stored in databases.Enforced
A08: Software & Data IntegrityHMAC-SHA256 timestamped signatures on outbound webhooks (X-Signature-SHA256) preventing tampering and replay.Enforced
A09: Logging & MonitoringStructured JSON logs with automated PII masking; Prometheus metrics tracking anomalous failure rates.Enforced
A10: SSRFWebhook 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.