From 749b619c1b3538a3b5ab5b04607cbb10d883bd65 Mon Sep 17 00:00:00 2001 From: Dev M Date: Sun, 6 Sep 2026 07:46:49 +0530 Subject: [PATCH] chore(security): harden public surface (2026-09-06) --- SECURITY.md | 10 +++++++++- vercel.json | 40 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index f967803..dc6de9a 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,6 +1,6 @@ # Security Assessment — CollabSpace -**Date:** 2026-08-21 +**Date:** 2026-09-06 **Scope:** Auth, XSS, injection, RLS, secrets, CORS, dependency risk **Context:** Public Vercel deploy is a **frontend-only shell** (no Supabase env). Full multiplayer needs a Supabase project. Schema in `supabase/migrations/0001_init.sql` is **open RLS** (no auth). @@ -147,3 +147,11 @@ npm run typecheck npm run test:e2e npm audit --omit=dev ``` + +## Repository visibility + +This repository is currently **public** for portfolio review. When the open-source +build story is no longer needed, **the GitHub repo will go private**. Making the +repo private reduces source disclosure; it does **not** replace strong production +secrets, auth allow-lists, webhook signatures, or Vercel/Actions environment +hygiene. Rotate any credential that was pasted into chat, tickets, or screenshots. diff --git a/vercel.json b/vercel.json index c6dbdbc..649f4d3 100644 --- a/vercel.json +++ b/vercel.json @@ -4,6 +4,44 @@ "outputDirectory": "client/dist", "framework": null, "rewrites": [ - { "source": "/(.*)", "destination": "/index.html" } + { + "source": "/(.*)", + "destination": "/index.html" + } + ], + "headers": [ + { + "source": "/(.*)", + "headers": [ + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "Referrer-Policy", + "value": "strict-origin-when-cross-origin" + }, + { + "key": "Permissions-Policy", + "value": "camera=(), microphone=(), geolocation=(), payment=(), usb=()" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=63072000; includeSubDomains; preload" + }, + { + "key": "Cross-Origin-Opener-Policy", + "value": "same-origin" + }, + { + "key": "X-DNS-Prefetch-Control", + "value": "off" + } + ] + } ] }