diff --git a/Security.md b/Security.md new file mode 100644 index 0000000..cfd1755 --- /dev/null +++ b/Security.md @@ -0,0 +1,85 @@ +# Security Policy + +This document describes how security is handled in the **Hoterstellar backend** (`abushayedgit/hoterstellar_sr`) and how to report a vulnerability. + +This is a **private, closed-source commercial project**. This policy is written for the small group of people with repository access (owner, contributor, and anyone the owner grants access to) — it is not an open-source public-disclosure program. + +--- + +## Supported Versions + +There is no version-branch matrix for this project — it is deployed continuously from a single production line. + +| Branch | Supported | +| --------------------------------------------------- | ------------------------------------------------ | +| `main` (production, deployed via `cd.yml` → Render) | ✅ Yes | +| `develop` | ✅ Yes (pre-production) | +| `feature/*`, `fix/*`, `refactor/*` | ❌ No — these are in-progress work, not deployed | +| Any fork | ❌ No | + +Only the code currently running in production (`main`) and the environment variables configured on the two live Render services (`hoterstellar-api`, `hoterstellar-worker`) are in scope for security concerns. + +--- + +## Reporting a Vulnerability + +**Do not open a public GitHub issue for a security vulnerability.** Issues are visible to anyone with repository access and are not an appropriate channel for reporting exploitable weaknesses before they're fixed. + +Instead: + +1. Contact the repository owner, **[@abushayedgit](https://github.com/abushayedgit)**, directly (or the contributor **[@heyAbdullahBruh](https://github.com/heyAbdullahBruh)**) via a private channel — direct message, email, or another agreed-upon secure channel. +2. Include: + - A clear description of the vulnerability and its potential impact. + - Steps to reproduce it (a minimal request/payload is ideal). + - The affected endpoint, module, or file, if known (e.g. `POST /api/v1/auth/user/signin`, `src/middlewares/auth.base.middleware.js`). + - Whether you believe it's already being exploited. +3. Do not test the vulnerability against production data beyond what's strictly necessary to demonstrate it. Do not access, modify, or delete another user's or admin's data. + +**Response expectations:** as a small, closed team, there is no formal SLA. Treat anything that looks like an authentication bypass, privilege escalation (e.g. a `manager`/`admin` account reaching `super_admin`-only actions), or data exposure across users as urgent and flag it as such when reporting. + +--- + +## Known, Already-Tracked Issues + +These are **not** new reports — they are documented gaps already tracked in `README.md` (see _Implementation Notes / Inconsistencies_ and _System Limitations_). Please don't re-report them; link back to those sections if you want to discuss fixing one: + +- Admin password reset (`POST /auth/admin/reset-password`) is unimplemented and always fails — the reset token generated by `request-reset-password` is never persisted. +- `src/middlewares/auth.base.middleware.js`'s `verifyAccessToken` calls `require("jsonwebtoken")` inside an ESM module, which is not valid Node.js ESM syntax. +- `src/app/bootstrap.js` references functions (`createApp`, `connectDatabase`) that don't exist in the files it imports from, and is not used by the running `server.js`. +- CSRF middleware (`setCsrfCookie`, `csrfProtection`) is registered in `src/app/app.js` after the API routes, 404 handler, and error handler — the effective enforcement order should be verified before relying on it. +- No automated test suite exists, so regressions in any of the above (or in auth/authorization logic generally) are not currently caught by CI. + +--- + +## Security Mechanisms Currently in Place + +For context when assessing a report's severity, here is what's actually implemented today (see `README.md` → _Security Architecture_ for full detail): + +| Layer | Mechanism | +| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Transport / headers | `helmet()`, custom CSP, HSTS (prod), `X-Frame-Options: DENY`, `X-Content-Type-Options: nosniff` | +| CORS | Explicit origin allow-list via `CORS_ORIGINS`, credentials enabled | +| Input handling | Null-byte/control-character sanitization, Zod schema validation on nearly every route, ObjectId format validation | +| Rate limiting | Four tiers — global, auth, mutation, admin-destructive (`src/middlewares/rateLimiter.middleware.js`) | +| AuthN | Separate JWT tracks for admins and users (`ADMIN_JWT_SECRET` / `USER_JWT_SECRET`), hashed + rotated refresh tokens, TTL-expiring sessions | +| AuthZ | Role/permission-based middleware (`super_admin` / `admin` / `manager`), with the most sensitive actions (admin deletion) gated by role rather than permission alone | +| CSRF | Double-submit cookie on the two refresh endpoints | +| Bot mitigation | Server-verified reCAPTCHA on public booking creation | +| Audit trail | `auditLog(action)` middleware on essentially all admin mutations | +| Secrets | Bcrypt (12 rounds) for admin passwords; refresh tokens stored only as SHA-256 hashes; `password`/`refreshTokenHash` stripped from every serialized document; sensitive fields redacted from logs | +| Config safety | Environment schema validated at boot (Zod); production boot hard-fails if critical secrets are missing | +| Dependency hygiene | `npm audit --audit-level=high` in CI/CD, CodeQL security scanning (weekly + on push/PR), GitHub Dependency Review on PRs, weekly Dependabot updates | + +None of this is described as "unhackable" or "enterprise-grade" — it's a description of what exists, and a report that finds a gap in or around any of the above is exactly the kind of report this policy wants. + +--- + +## Secrets and Credentials + +- Never commit `.env`, real API keys, database URIs, or JWT secrets to this repository. Only `.env.example` (with placeholder values) belongs in version control. +- If a secret is ever accidentally committed (even in a since-reverted commit — it's still in git history), treat it as compromised: rotate it immediately in Render's environment variable settings and in the upstream provider (MongoDB Atlas, Upstash, Brevo, ImageKit, Google reCAPTCHA), not just in `.env`. +- `ADMIN_JWT_SECRET` and `USER_JWT_SECRET` must each be at least 32 characters (enforced by `src/config/env.js`) and should be generated independently, not derived from each other. + +## Dependency Updates + +Dependabot is configured (`.github/dependabot.yml`) to open weekly PRs for both npm packages and GitHub Actions. Security-relevant updates (flagged `high` severity or above by `npm audit` / GitHub's Dependency Review) should be prioritized ahead of routine dependency bumps.