Trust & Safety
Security at StopBouncing
We take the security of your account and your data seriously. Here is a transparent overview of the measures we have in place.
Authentication
- Passwords hashed with bcrypt (cost factor 12) — never stored in plain text
- Session tokens are cryptographically signed JWTs; a password reset invalidates all active sessions
- Rate limiting on login (5 attempts per 15 minutes per IP) and registration (3 per hour per IP)
- Constant-time password comparison to prevent timing-based user enumeration
- Email verification required before accessing the service
API keys
- API keys are hashed with SHA-256 on creation — the raw key is shown once and never stored
- Keys are prefixed (sb_…) to allow identification without revealing the full key
- Keys can be revoked instantly from the dashboard
- Rate-limited to 60 requests per minute per key
- Suspended accounts have all API keys revoked automatically
Infrastructure
- All traffic is served exclusively over HTTPS with HSTS enforced (max-age 2 years, includeSubDomains, preload)
- HTTP security headers: Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy
- Servers hosted in the EU — data does not leave the European Economic Area
- Database credentials and API keys are stored only as environment variables, never in code or version control
- Prisma ORM with parameterised queries — SQL injection is not possible
Data minimisation and retention
- Uploaded email files are not stored — they are parsed in memory and the parsed rows are held for job processing only
- Verification results are available for download for 7 days after job completion, then permanently purged
- Verification tokens (email confirmation, password reset) are purged 30 days after use or expiry
- Audit logs are retained for 1 year, then automatically purged
- Financial records are retained for 7 years to comply with Dutch tax law
Monitoring and audit
- Security-relevant actions (login, password reset, API key creation/revocation, admin actions) are written to an immutable audit log
- Audit log entries include actor ID, timestamp, action, and relevant metadata
- Credit mutations always happen in a database transaction alongside a ledger entry — the balance can always be reconstructed from the ledger
Payment security
- Payments are handled exclusively by Stripe — we never see or store card numbers
- Stripe webhooks are verified using HMAC signature verification before any action is taken
- Credits are only granted after payment confirmation via webhook — the UI cannot trigger credit grants directly
- Idempotency keys prevent webhook replay from granting credits more than once per purchase
Found a security issue?
Please report it responsibly through our Responsible Disclosure Policy.