Security posture · last updated 2026-05-15

Security is the product. Here's how we run it on ourselves.

This page documents how PhishFence handles your data, what we hold and don't hold, the cryptographic and operational controls we run, and an honest list of certifications we don't have yet. Updated whenever the posture changes.

Data we hold — and data we don't

We storeWe do not store
  • · Customer email address (account identifier)
  • · Bcrypt-hashed password (cost 12)
  • · Monitored domain names
  • · Lookalike scan results & risk scores
  • · DMARC aggregate reports (RUA)
  • · Screenshots of suspect domains
  • · Alert configurations & notification routing
  • · API token hashes (keyed BLAKE2b, plaintext shown once at creation)
  • · Audit log of security-relevant events
  • · Billing metadata via Stripe (subscription IDs, plan)
  • · Message bodies or customer email contents
  • · End-user PII beyond what's required for the account
  • · DMARC forensic reports (RUF) — opt-in only
  • · Payment card numbers (handled by Stripe)
  • · Plaintext passwords
  • · Plaintext API tokens after creation
  • · Browser cookies for third-party advertising
  • · Cross-site tracking pixels

Encryption

At restPostgreSQL on Google Cloud SQL with disk encryption enabled (production). SQLite for local development only. Passwords bcrypt-hashed (cost 12). API tokens stored as keyed BLAKE2b hashes — plaintext is shown to the user once at creation and never persisted.
In transitTLS 1.2 or higher on every external endpoint. HSTS enforced with max-age=31536000; includeSubDomains; preload. HTTP requests upgraded via upgrade-insecure-requests CSP directive.
Inbound mailMTA-STS published at mta-sts.phishfence.io in enforce mode — senders refuse to deliver mail to phishfence.io over non-TLS.
SecretsStored as environment variables provisioned by Google Cloud Run from Secret Manager. Never committed to source control. The JWT signing key, Stripe secret key, Resend API key, and database URL are all managed this way.

Authentication

MethodStatusNotes
Email + passwordLive10-character minimum, requires letter + number + special char, blocklist of common passwords. Bcrypt hashed.
Magic-link loginLiveSingle-use token, 15-minute expiry.
Google OAuth loginLiveOIDC; standard Google sign-in.
Email verification on signupLiveRequired before sensitive actions.
Password resetLiveEmail-delivered single-use token. Token reuse and brute force rate-limited per IP and per email.
Session tokensLiveJWT in HttpOnly Secure SameSite=Lax cookie, 2-day rolling lifetime. Bumping the user's password invalidates all prior tokens.
API tokensLiveKeyed BLAKE2b hashed at rest, rate-limited to 60 req/min per token, max 10 tokens per user.
TOTP / 2FAPlanned Q3 2026RFC 6238 TOTP. Recovery codes generated at enrollment.
SSO (SAML / OIDC)On requestWill be added when the first enterprise customer requires it. Talk to us.
Hardware keys (WebAuthn / passkeys)BacklogBacklogged; not currently scheduled.

Authorization & tenant isolation

  • · Every dashboard and API endpoint scopes queries by the authenticated user's user_id — cross-tenant data exposure would require a deliberate SQL injection on top of an auth bypass.
  • · CSRF tokens enforced on every state-changing request (POST, PATCH, DELETE) via a dedicated middleware.
  • · Rate limiting on auth endpoints (10/min per IP) and on the public domain checker (3/hour per IP).
  • · Admin endpoints gated by an is_admin flag set out-of-band — not "first user wins".
  • · Team-based features (multi-user accounts) enforce both team membership and per-feature plan gates before granting access.

Application security

Content-Security-PolicyStrict CSP with default-src 'self', no unsafe-inline on script-src, frame-ancestors 'none', and object-src 'none'.
ClickjackingX-Frame-Options: DENY in addition to the CSP frame-ancestors.
MIME sniffingX-Content-Type-Options: nosniff.
Referrer policystrict-origin-when-cross-origin.
Permissions policyCamera, microphone, geolocation, payment, and other powerful APIs all blocked at the browser level.
Output encodingJinja2 autoescape enforced. User-supplied content rendered via standard template variables, never |safe.
Input validationPydantic models on every API endpoint, server-side validation on every form. Domain inputs canonicalized and length-capped before storage.
Web application firewallApplication-level WAF middleware that bans IPs hitting common attack signatures (path traversal, SQLi probes, scanner UAs).
Prompt injectionLLM-backed features (DMARC analysis assistant) treat all outputs as untrusted content. Generated text is rendered, never executed, never used as a tool call.
DependenciesPinned versions in requirements.txt. Reviewed for known CVEs prior to deploy.

Operational security

  • · Hosting: Google Cloud Run for the web tier; Cloud SQL (PostgreSQL) for the data tier; Cloud Run Jobs for scanning workloads; Cloud Scheduler for orchestration. US region.
  • · Backups: Automated Cloud SQL backups with 30-day retention. Point-in-time recovery enabled.
  • · Error monitoring: Sentry. Personally identifiable fields are scrubbed before transmission; message bodies and customer email contents are never sent.
  • · Email sending: Resend (transactional only: account verification, password reset, alert notifications). DMARC enforced on phishfence.io's sending domain.
  • · Logs: Structured JSON logs to Google Cloud Logging; standard 30-day retention. Audit log of security-sensitive actions retained 90 days at minimum.
  • · Deploys: All deploys go through Cloud Build with automated tests, type checks, and security scans. Production deploys are gated behind manual approval.

Incident response

  • · Affected customers will be notified within 72 hours of confirmed incident affecting their data, mirroring the GDPR Article 33 timeline.
  • · Notification goes to the email address of record on the affected account, plus a public post-mortem if the incident is wide-scope.
  • · Detection inputs include Sentry alerts, Cloud Logging metrics, abuse signals from the WAF, and customer reports to security@phishfence.io.
  • · The status page at status.phishfence.io is the canonical communication surface for ongoing incidents. (Status page is being stood up; if you reach it before it's live, please email support@phishfence.io.)

Account & data deletion

Account deletion is a self-service action from Settings → Delete account. Confirmation requires re-typing your account email. On confirmation, in a single database transaction we:

  1. Cancel any active Stripe subscription so billing stops immediately.
  2. Delete monitored domains and every alert, alert event, screenshot, and phishing report attached to them.
  3. Delete pending email verifications, password resets, feedback, API tokens, and team memberships.
  4. Null out the user_id on retained audit-log entries (we keep the event records so a forensic trail survives the deletion).
  5. Hard-delete the user row itself.

Sentry sweeps any cached error context for the deleted user on its 30-day rolling window. Backups containing your data age out per the 30-day backup retention.

Owners of teams with active members must transfer ownership or dissolve the team before deletion can proceed.

What we don't have yet

We'd rather you ask once and get the truth than discover it later in your security questionnaire. Here's what we're missing today and when we expect to close each gap.

ControlStatus & plan
SOC 2 Type 1Not yet. Targeted for 2027 once revenue justifies the audit cost (~$15–25K plus ongoing). We operate to SOC-2-aligned controls today but do not hold a formal attestation.
SOC 2 Type 2Not yet. Follows Type 1 by the standard 6-month observation period.
Third-party penetration testNot yet. Targeted for Q4 2026. We'll publish the executive summary; the full report goes out under NDA.
HIPAA / BAANot supported. PhishFence is not designed for protected health information; do not store PHI in monitored-domain notes or alert configurations.
FedRAMPNot planned. PhishFence is not certified for US Federal Government use.
ISO 27001Not yet. Following SOC 2.
GDPR formal certificationWe operate to GDPR-aligned principles today (data deletion implemented, sub-processors disclosed, EU-resident customers treated as data subjects) but do not hold a formal certification.
Public bug bounty programNot yet. We accept vulnerability reports via security@phishfence.io and the security.txt contact. Responsible disclosure welcomed; a formal program with rewards is planned post-pen-test.

Report a vulnerability

Send vulnerability reports to security@phishfence.io. Our coordinates are also published per RFC 9116 at /.well-known/security.txt.

Please include reproduction steps, the affected endpoint or URL, and any proof-of-concept payload. We respond within one business day and aim to issue an initial fix or mitigation within 7 days for high-severity issues. We won't pursue legal action against researchers who follow standard responsible-disclosure norms.

Get in touch