Security
Security at Social Perks
We treat security as a product surface, not a compliance checkbox. This page lists what we do, where the limits are, and how to report a vulnerability.
Authentication
- Passwords stored with scrypt + per-password salt; no plaintext.
- JWT signing pinned to HS256 with explicit type-claim verification (access vs refresh).
- API keys hashed with SHA-256 before persistence; verification uses constant-time compare.
- Demo PIN auth disabled in production — only password and JWT/cookie paths accept logins.
- OAuth state tokens are server-side single-use (atomic consume on callback).
Authorization & tenant isolation
- Every cross-tenant resource access goes through `requireOwnership(user, resource.businessId)` — explicit fail-closed (no null-bypass).
- API key permissions enforced at the route layer; keys cannot mint or list other keys.
- Cross-tenant cashback / submission attempts return 404 (not 403) to avoid resource-existence enumeration.
Network & transport
- HSTS with includeSubDomains + preload.
- Strict CSP — script-src nonce-tightened, connect-src allowlisted, object-src none, upgrade-insecure-requests.
- X-Frame-Options DENY + CSP frame-ancestors none — clickjacking blocked.
- SSRF guard on all server-side fetches (RFC1918 / loopback / cloud-metadata IPs blocked, redirects manual).
Webhook integrity
- Stripe webhooks: HMAC-SHA256 signature verification via Stripe SDK (constant-time).
- Platform webhooks (Meta, TikTok, etc.): HMAC-SHA256 signature with replay protection (cross-instance via Postgres).
- Signature failures are audit-logged; production hard-fails when secrets are missing rather than degrading silently.
Data handling
- API key plaintext is shown ONCE at creation, never persisted.
- Database connection over TLS (Postgres default in production).
- Audit log captures security-sensitive events (auth, key lifecycle, billing changes, submission reviews) with structured JSON output.
- No customer payment data ever stored on Social Perks — Stripe handles the entire payment surface.
- PII (email, phone) is per-tenant-isolated; cross-tenant queries reject in the repository layer.
Dependencies
npm auditruns on every PR; high-severity CVEs block merge.- Renovate/Dependabot on autoupdate for non-breaking patches.
- No bundled binaries from third parties.
Vulnerability disclosure
If you discover a security issue, please report it to security@socialperks.app with steps to reproduce. We commit to:
- Acknowledging receipt within 24 hours.
- Investigating within 5 business days.
- Patching critical issues within 7 days, others within 30.
- Crediting the reporter (with permission) in our changelog.
- Not pursuing legal action against good-faith research.
Incident response
For active incidents: status updates land at /status. Customer notifications go via the email address on record. Post-mortems for incidents touching customer data are published in the changelog within 14 days.
What we don't do (yet)
- SOC 2 Type 2 certification — on the roadmap; not currently audited.
- Bug bounty program — handled ad-hoc on the disclosure email above.
- Penetration testing on an annual schedule — last test was internal-only.
We're a small team. We tell you what's done and what isn't.