Security
This describes what is actually implemented, not an aspiration. Where something is not done, it says so.
Accounts and sessions
- Passwords are bcrypt-hashed at 12 rounds. We cannot read your password, and neither can anyone who obtains the database.
- Sessions are opaque random tokens, stored only as SHA-256 hashes. Not self-contained JWTs. That costs one lookup per request and buys instant revocation: signing out, or an account being suspended, takes effect on the very next request rather than whenever a token would have expired. A database leak also cannot be replayed as a live login.
- The session cookie is
HttpOnly, so page scripts cannot read it, andSameSite=Laxso other sites cannot send it. - The mobile app never receives a token in a browser-readable place. The API returns a bearer token only to a caller that identifies itself as the native app, and the app stores it in the device keychain. Web responses never contain the token — that is enforced by a test with a negative control, because the whole point of the
HttpOnlycookie is undone the moment a token appears in a JSON body. - Sign-in does not reveal whether an email is registered. A wrong password and an unknown account return the same message, and the password comparison runs against a dummy hash when the account does not exist so the timing does not differ either.
Keeping customers separate
- Every query is scoped to your workspace, from the session — never from anything in the request. Asking for a video, product, or connected channel that belongs to someone else returns the same 404 as one that does not exist, so the API cannot be used to discover other customers’ identifiers. A 403 would confirm the record exists somewhere.
- The media proxy checks ownership before serving a byte, and rejects path traversal. Finished videos are served by this app, not from a public bucket.
- This is covered by automated tests that attempt cross-tenant reads and expect them to fail.
Payments
- No card details ever reach us. Checkout is Stripe’s own hosted page. There is no publishable key in our client and no card field in our interface, so our PCI surface is effectively nil.
- Access is granted by the Stripe webhook, not by the browser redirect. A redirect can be lost — a closed tab, a dropped connection — and if it were the thing that provisioned the account, a customer could pay and receive nothing.
- Webhook signatures are verified. Credit grants are idempotent on the Stripe event id, so a replayed webhook cannot double-credit.
- An unrecognised price never downgrades a paying customer.
Connected social channels
- Access tokens are encrypted at rest with AES-256-GCM, and the API that lists your channels never selects the token column.
- New posts default to private or unlisted wherever the platform allows it, because publishing cannot be undone.
- Disconnecting a channel deletes its tokens. A token the platform rejects is marked invalid so the app asks you to reconnect rather than silently failing.
Spending and abuse
Generation costs real money, so the accounting is defensive by design. Credits are held before work starts and settled against what actually ran. Each job is claimed by a compare-and-swap, so two workers can never pick up the same job and generate — and pay for — it twice. Every step writes its own cost to a ledger you can inspect.
Infrastructure
- HTTPS only, with HSTS. Certificates renew automatically.
- Security headers are set at the application: a Content-Security-Policy,
X-Frame-Options: DENY,nosniff, a restrictiveReferrer-Policy, and aPermissions-Policydenying camera, microphone and geolocation. - The database is not reachable from the internet. Backups are encrypted.
- Secrets live in environment configuration on the host, never in the repository. The build fails on a type or lint error, so a broken deploy cannot reach customers.
What we have not done yet
Stated plainly, because a security page that lists only strengths is marketing:
- No SOC 2 or ISO 27001 certification. We are a small team and have not been audited.
- No third-party penetration test yet.
- No two-factor authentication on customer accounts yet. It is planned.
- No formal bug-bounty programme — but see below.
Reporting a vulnerability
Email support@storeswiki.com with “security” in the subject. Tell us what you found and how to reproduce it. We will acknowledge within two business days and keep you posted until it is fixed. Please give us a reasonable window before disclosing publicly, do not access other customers’ data, and do not run load or denial-of-service tests against production. We will not pursue anyone acting in good faith under those conditions.
Last updated 4 August 2026. StoresWiki LLC, Lewes, Delaware, USA. Questions about this page: support@storeswiki.com.