Identity and sessions
- Passwords must be at least 12 characters and are hashed using Argon2id.
- Repeated failed login attempts trigger a temporary credential lock.
- Short-lived access tokens are paired with hashed, rotating refresh sessions in an HttpOnly Secure cookie.
- TOTP multi-factor authentication and one-time recovery codes are available; high-risk account, Meta, export, and billing actions require recent MFA.
- Password change, password reset, logout, user disabling, membership changes, and explicit revocation invalidate affected sessions.
Tenant isolation and permissions
The active tenant comes from the authenticated server-side session rather than a tenant ID supplied by the browser. Protected requests reload active user, session, membership, and role state. Tenant-owned database queries and important relationship constraints include the tenant identifier.
API permissions cover Owner, Admin, Manager, Agent, and Analyst roles. Separate internal administration endpoints require explicit super-admin status plus recent MFA. Automated integration tests exercise cross-tenant direct-ID access and role denials. PostgreSQL row-level security is not currently used and is not claimed.
Provider credentials and ingress
- Meta access tokens are encrypted at the application layer with AES-256-GCM and a deployment key.
- Meta and Razorpay webhook requests are verified over their exact raw body with provider-specific HMAC secrets before processing.
- Valid webhook receipts are deduplicated, persisted, and processed asynchronously to tolerate retries.
- Meta Embedded Signup state is random, expiring, single-use, and bound to the authenticated user, tenant, and session.
- Campaign recipient jobs and provider message IDs use deterministic uniqueness and ambiguous-outcome handling to reduce duplicate sends.
Data, files, and privacy controls
- HTTPS is enforced at the public edge with HSTS, content, frame, MIME, referrer, browser-permission, and origin controls.
- Production PostgreSQL, Redis, and private S3-compatible storage are not exposed directly to the internet.
- Imports and campaign media have file-size, type, archive, signature, and integrity checks; campaign media is malware-scanned before short-lived signed links can be used by Meta.
- Structured logs redact credentials and known token fields and are designed not to log raw message bodies, imports, or webhook bodies.
- Consent is checked when audiences are created and again immediately before provider send; STOP-like inbound replies record an opt-out.
Campaign files are held in a private asynchronous quarantine until their saved size, checksum, type, signature, and malware scan pass. Inbound WhatsApp attachments are retrieved separately with bounded Meta-host checks and are also exposed only after validation and a clean malware scan. Blocked, failed, and expired attachments remain unavailable.
Operations, recovery, and limitations
Services run as non-root application users in health-checked containers with resource limits. Release gates include formatting, linting, TypeScript checks, automated tests, production builds, dependency audit, migration checks, backup integrity, and isolated restore verification. Daily compressed database backups are kept locally for 14 days.
Current production does not claim SOC 2, ISO 27001, independent penetration testing, managed KMS, SIEM coverage, point-in-time recovery, high availability, or off-host disaster recovery. Same-server backups do not protect against total VPS loss. Those controls must be operated and evidenced before stronger availability or recovery claims are made.
Responsible disclosure
Send a suspected vulnerability privately to support@sendinbox.co with “Security report” in the subject. Include the affected URL or feature, impact, reproducible steps, and a safe proof. Do not include data obtained from another account.
Act in good faith: use your own workspace, avoid privacy violations and disruption, do not access or retain other people’s data, do not use automated volumetric testing, and give us reasonable time to investigate before disclosure. We do not currently operate a paid bug bounty. We will acknowledge a verifiable report and coordinate remediation and disclosure based on severity.