Skip to content

Security: Ovalvoi/GroundShare

docs/SECURITY.md

Security Policy — GroundShare

Reporting Vulnerabilities

If you discover a security vulnerability, please email security@groundshare.app with:

  • Description of the vulnerability
  • Steps to reproduce
  • Potential impact

Do NOT open a public GitHub issue for security vulnerabilities.

Security Architecture

Authentication

  • JWT Bearer tokens (access: 15min, refresh: 7 days with rotation)
  • Access tokens stored in memory only (not localStorage)
  • Google OAuth via official Google.Apis.Auth library with audience validation
  • BCrypt password hashing (work factor 12)

Secrets Management

  • All production secrets stored in Azure Key Vault
  • App Service authenticates via Managed Identity (no secrets in env vars)
  • appsettings.json contains only placeholder values
  • Pre-commit hook (gitleaks) blocks accidental secret commits

Input Validation

  • FluentValidation on all API request DTOs
  • File uploads validated by magic-byte sniffing (not just Content-Type)
  • All database access uses parameterized stored procedures

Rate Limiting

  • /auth/login: 5/min per IP
  • /auth/register: 3/hour per IP
  • /api/files/upload: 20/min per IP
  • Global: 100/min per IP

Security Headers

  • Content-Security-Policy on both API and frontend
  • Strict-Transport-Security (HSTS, 1 year)
  • X-Frame-Options: DENY
  • X-Content-Type-Options: nosniff
  • Referrer-Policy: strict-origin-when-cross-origin
  • Permissions-Policy: camera=(), microphone=(), geolocation=()

Blob Storage

  • Private container (no public access)
  • Time-limited SAS URLs for read access (1 hour)
  • Managed Identity for write access (no connection strings)

Key Rotation Schedule

Secret Rotation How
JWT signing key Every 90 days Update Jwt--Key in Key Vault
Google API keys Every 90 days Regenerate in Google Cloud Console, update Key Vault
SQL admin password Every 90 days az sql server update, update Key Vault

Backup & Recovery

Data Backup Retention
Azure SQL Automatic point-in-time restore 7 days (Basic tier)
Blob Storage Soft delete enabled 7 days
Key Vault Soft delete + purge protection 90 days

Data Deletion (GDPR)

To delete a user's data:

  1. Delete from [user] table (cascades to events, reviews, comments, votes, favorites, notifications)
  2. Delete associated blobs from Azure Storage
  3. Remove entries from [audit_log] after retention period

Monitoring & Incident Response

  • Application Insights captures all request/error telemetry
  • Alert: 5+ server exceptions in 5 minutes triggers email notification
  • Audit log table records: login success/failure, password changes, account deletion
  • Structured logging via Serilog with PII redaction

CI/CD Security

  • gitleaks: Secret scanning on every PR
  • npm audit: Dependency vulnerability check (HIGH+CRITICAL block merge)
  • dotnet list package --vulnerable: NuGet vulnerability check
  • Dependabot: Weekly dependency update PRs

Refresh-Token Rotation Hardening (implemented)

Refresh-token rotation is single-winner with a grace window and token-reuse detection — the whole flow is in RefreshTokenDAL + sp_RotateRefreshToken / the reuse-detection SP in GroundShareDB.sql:

  • Atomic rotation (sp_RotateRefreshToken): revoke the presented token and record its successor's hash on refresh_token.Replaced_By in one statement, so a token is never left revoked-with-no-replacement.
  • Race-safe (grace window): two near-simultaneous refreshes of the same token (e.g. two tabs) no longer log the user out — the loser sees the token revoked-recently with a Replaced_By and is handed back the recorded successor instead of a 401. The frontend's single-flight guard (refreshPromise in services/api/client.ts) still collapses concurrent refreshes within one client.
  • Reuse detection (theft signal): a revoked token replayed outside the grace window stamps Reused_At, revokes every still-active token for the user, and nulls out Replaced_By across the whole family so no family token can mint a fresh session afterward.

This closes what was previously logged here as a deferred backlog item.

Known Issues (Backlog)

  • No DB migration versioningGroundShareDB.sql is a single re-runnable script; schema history and rollback are by hand. Acceptable at current scale; revisit if the schema churn or the team grows.

There aren't any published security advisories