arrow_backBack

Security Policy

Last updated: March 2026

Supported Versions

VersionSupported
mainYes

Only the latest version on the main branch receives security updates.

Reporting a Vulnerability

Please do not open a public GitHub issue for security vulnerabilities.

Report vulnerabilities by emailing the maintainer directly (see the repository's contact information). Include as much detail as possible:

  • A description of the vulnerability and its potential impact
  • Steps to reproduce or a proof-of-concept
  • The affected component(s) and version/commit
  • Any suggested mitigations

You will receive an acknowledgement within 48 hours and a more detailed response within 5 business days outlining next steps. Once the fix is deployed, you will be credited in the release notes unless you request anonymity.

Security Controls

Authentication & Session Management

  • JWT access tokens (15-minute expiry) issued on login/registration
  • Refresh tokens are SHA-256 hashed before storage and rotated on every use
  • Account lockout: 5 failed login attempts triggers a 15-minute lockout per email address
  • Google OAuth tokens are never exposed in redirect URLs — a short-lived (90s) server-side code is exchanged instead
  • Password reset tokens are SHA-256 hashed in the database and expire after 1 hour; successful reset revokes all active sessions

Password Policy

All user-set passwords must meet the following requirements:

  • Minimum 8 characters
  • At least one uppercase letter (A–Z)
  • At least one lowercase letter (a–z)
  • At least one digit (0–9)

Transport Security

  • All API endpoints should be served over HTTPS in production
  • helmet middleware sets security headers (HSTS, X-Frame-Options, X-Content-Type-Options, etc.)
  • CORS is restricted to the configured WEB_URL origin
  • SameSite=Lax; Secure cookies are used for OAuth state and optional session data

Rate Limiting

Endpoint categoryWindowLimit
Global (all routes)1 min100
Auth (login, register)15 min10
Guest login5 min30
Room creation1 hour20
Forgot/reset password15 min10
Socket: join room1 min10
Socket: submit vote1 min30

Data Storage

  • Passwords hashed with bcrypt (cost factor 12)
  • Jira OAuth tokens encrypted at rest using AES-256-GCM with an application-level secret key
  • No raw tokens stored in the database
  • Redis keys for live room state have a 24-hour TTL

Administrative Endpoints

POST /api/v1/rooms/cleanup requires the X-Admin-Key header matching the ADMIN_API_KEY environment variable; returns 503 if unconfigured.

Input Validation

  • All request bodies validated with Zod schemas before reaching service layer
  • String fields trimmed and normalised (emails lowercased)
  • Jira issue URLs validated as valid HTTP/HTTPS URLs
  • JSON request bodies limited to 64 KB
  • Room names, passwords, and vote values have explicit max-length constraints

Known Limitations & Roadmap

IssueStatus
JWTs stored in localStorage (XSS risk)Planned: migrate to HttpOnly cookie storage
No email verification on registrationPlanned
CSRF tokens not implementedLow risk with JWT-in-header auth; will be required if cookie auth is fully adopted
No Sentry/error-monitoring in productionPlanned
Password reset emails logged to stdout (dev only)Needs email provider integration before production

Responsible Disclosure

We follow a 90-day disclosure timeline: vulnerabilities reported to us will be disclosed publicly no earlier than 90 days after the initial report, or after a patch is released — whichever comes first.

© 2025 Sprint Poker Online