Security

Security Practices

This page describes the security measures currently in place across the Reviewlico platform. All claims here reflect the actual implementation — nothing is aspirational.

1. Password storage

Passwords are hashed with bcrypt using 12 salt rounds before being stored. Plaintext passwords are never written to the database, logged, or included in API responses. Authentication compares the submitted password against the stored hash using a timing-safe comparison.

2. Authentication tokens

Authenticated sessions use two tokens: a short-lived access token (JWT, 15-minute expiry) sent in the Authorization header, and a refresh token delivered as an httpOnly cookie.

Refresh tokens are hashed with SHA-256 before storage. On each refresh, the old token is revoked and a new pair is issued (token rotation). The refresh cookie is set with httpOnly, sameSite=lax, and secure in production, so it is never accessible to client-side JavaScript.

3. API key handling

Organization API keys are generated from cryptographically random bytes. The raw key is shown exactly once at creation time — only the SHA-256 hash is stored in the database. Lookups compare hashes, never plaintext.

API keys are scoped to a single organization and only grant access to public endpoints (submitting and listing reviews, listing products). They cannot access the dashboard or modify account settings.

4. Rate limiting

All endpoints are rate-limited to prevent abuse. Limits are enforced per minute and vary by endpoint type:

  • Authentication — login: 10/min, registration: 5/min, email verification: 5/min, token refresh: 20/min (all per IP)
  • Public API — review submission: 20/min, review listing: 120/min, product listing: 60/min (per API key or IP)
  • Dashboard — 100/min per authenticated user

Standard rate-limit headers (RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset) are included in responses so clients can adapt.

5. Security headers

The API uses Helmet to set secure HTTP headers by default. Both the API and the frontend enforce:

  • X-Content-Type-Options: nosniff — prevents MIME-type sniffing
  • X-Frame-Options: DENY — blocks clickjacking via iframes
  • Referrer-Policy: strict-origin-when-cross-origin — limits referrer leakage

Dashboard routes are additionally tagged with X-Robots-Tag: noindex, nofollow to prevent search engine indexing of authenticated pages.

6. Transport and CORS

Production deployments run over HTTPS exclusively. The refresh-token cookie has the secure flag enabled in production, ensuring it is only sent over encrypted connections.

CORS is configured in two tiers: public API endpoints allow all origins (the API key is the security boundary), while dashboard endpoints restrict origins to the configured frontend URL and require credentials.

7. Input validation

Request bodies are limited to 100 KB to mitigate payload-based attacks. Passwords must meet complexity requirements: minimum 8 characters with at least one uppercase letter, one lowercase letter, and one digit.

All database queries go through Mongoose ODM, which applies schema validation and parameterized queries to prevent injection attacks. Object IDs are format-validated before use.

8. Responsible disclosure

If you discover a security vulnerability in Reviewlico, please report it to support.reviewlico@gmail.com with a description of the issue and steps to reproduce. Reports will be acknowledged and investigated.