🧪 Security Fixes Testing Guide¶
Quick Test Checklist¶
Run these tests to verify all security fixes are working correctly.
✅ Test 1: Verify SSH Keys Are Ignored by Git¶
Goal: Confirm SSH keys won't be committed
Steps:
# 1. Check if keys are tracked by git
git ls-files | Select-String "key|\.key|_key"
# 2. Create a test key file (to verify .gitignore works)
New-Item -Path "config/deploy/test_key" -ItemType File -Force
New-Item -Path "config/deploy/test_key.pub" -ItemType File -Force
# 3. Check git status - these files should NOT appear
git status
# 4. Clean up test files
Remove-Item "config/deploy/test_key"
Remove-Item "config/deploy/test_key.pub"
Expected Result:
- No key files should appear in git status
- If you see key files, .gitignore isn't working properly
✅ Test 2: Verify Hardcoded Secrets Are Removed¶
Goal: Confirm docker-compose.yml requires environment variables
Steps:
# 1. Check docker-compose.yml for hardcoded defaults
Select-String -Path "docker-compose.yml" -Pattern "API_KEY.*:-|POSTGRES_PASSWORD.*:-"
# 2. Try to start without env vars (should fail)
# First, backup your .env
Copy-Item .env .env.backup
# Temporarily rename .env
Rename-Item .env .env.temp
# Try docker-compose (should fail or show errors)
docker-compose config
# Restore .env
Rename-Item .env.temp .env
Expected Result: - No matches in step 1 (no hardcoded defaults) - Step 2 should show errors about missing environment variables
✅ Test 3: Verify Supabase Key Requires Environment Variable¶
Goal: Confirm frontend fails gracefully without env var
Steps:
# 1. Check if hardcoded key is removed
Select-String -Path "frontend/src/config/supabase.ts" -Pattern "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
# 2. Temporarily remove env var and test
# In frontend/.env or root .env, comment out:
# VITE_SUPABASE_ANON_KEY=...
# 3. Try to build/start frontend
cd frontend
npm run dev
# Should show error about missing VITE_SUPABASE_ANON_KEY
Expected Result: - No hardcoded key found in step 1 - Frontend should fail with clear error message about missing env var
✅ Test 4: Verify Authentication Is Always Required¶
Goal: Confirm no auth bypass in development mode
Steps:
# 1. Check middleware.py for dev bypass
Select-String -Path "backend/middleware.py" -Pattern "development.*unauthenticated|ENVIRONMENT.*development.*call_next"
# 2. Test API endpoint without auth token
# Start your backend server
# Then in another terminal:
$headers = @{
"Content-Type" = "application/json"
}
# Don't include Authorization header
Invoke-RestMethod -Uri "http://localhost:8000/api/health" -Method GET -Headers $headers
# 3. Test with invalid token
$headers = @{
"Authorization" = "Bearer invalid_token_12345"
"Content-Type" = "application/json"
}
try {
Invoke-RestMethod -Uri "http://localhost:8000/api/components/search" -Method POST -Headers $headers -Body '{}'
} catch {
Write-Host "Status: $($_.Exception.Response.StatusCode.value__)"
Write-Host "Expected: 401 Unauthorized"
}
Expected Result: - Step 1: No matches (dev bypass removed) - Step 2: Should get 401 Unauthorized (or endpoint requires auth) - Step 3: Should get 401 Unauthorized
✅ Test 5: Verify CSP Headers Are Applied¶
Goal: Confirm Content Security Policy is working
Steps:
# 1. Check CSP doesn't have unsafe-inline/unsafe-eval for scripts
Select-String -Path "backend/main.py" -Pattern "script-src.*unsafe-inline|script-src.*unsafe-eval"
# 2. Start your backend server
# Then check headers:
$response = Invoke-WebRequest -Uri "http://localhost:8000/health" -Method GET
$response.Headers["Content-Security-Policy"]
# 3. Check browser console (if frontend is running)
# Open browser DevTools → Console
# Look for CSP violations (should be minimal/none)
Expected Result:
- Step 1: Should NOT find unsafe-inline or unsafe-eval in script-src
- Step 2: Should see CSP header in response
- Step 3: No CSP violation errors in console
✅ Test 6: Verify CORS Restrictions¶
Goal: Confirm CORS only allows specific origins
Steps:
# 1. Check CORS middleware doesn't allow all origins
Select-String -Path "backend/middleware/cors.js" -Pattern "callback\(null, true\)" -Context 2
# 2. Test from unauthorized origin
$headers = @{
"Origin" = "https://malicious-site.com"
"Content-Type" = "application/json"
}
try {
Invoke-RestMethod -Uri "http://localhost:8000/api/health" -Method GET -Headers $headers
} catch {
Write-Host "CORS blocked: $($_.Exception.Message)"
}
# 3. Test from allowed origin (localhost)
$headers = @{
"Origin" = "http://localhost:5173"
"Content-Type" = "application/json"
}
$response = Invoke-RestMethod -Uri "http://localhost:8000/api/health" -Method GET -Headers $headers
Write-Host "Allowed origin works: $($response -ne $null)"
Expected Result: - Step 1: Should show restricted origins, not wildcard - Step 2: Should be blocked (CORS error) - Step 3: Should work (allowed origin)
✅ Test 7: Verify Webhook Signature Enforcement¶
Goal: Confirm webhooks require valid signatures
Steps:
# 1. Check webhook code requires signature
Select-String -Path "backend/routes/webhooks.py" -Pattern "SUPABASE_WEBHOOK_SECRET.*not set.*reject|raise.*401.*webhook"
# 2. Test webhook without signature
$headers = @{
"Content-Type" = "application/json"
}
$body = @{
type = "INSERT"
table = "users"
record = @{
id = "test-123"
email = "test@example.com"
}
} | ConvertTo-Json
try {
Invoke-RestMethod -Uri "http://localhost:8000/api/webhooks" -Method POST -Headers $headers -Body $body
} catch {
Write-Host "Status: $($_.Exception.Response.StatusCode.value__)"
Write-Host "Expected: 401 if secret not set, or 401 if signature invalid"
}
Expected Result: - Step 1: Should find code that rejects webhooks without secret - Step 2: Should get 401 error
✅ Test 8: Verify Error Messages Are Sanitized¶
Goal: Confirm production doesn't expose internal errors
Steps:
# 1. Check error handler code
Select-String -Path "backend/main.py" -Pattern "is_production.*HTTPException|detail.*internal error"
# 2. Set ENVIRONMENT=production temporarily
$env:ENVIRONMENT = "production"
# 3. Trigger an error (if you have a test endpoint that throws)
# Check response - should be generic message, not full traceback
# 4. Restore environment
$env:ENVIRONMENT = "development"
Expected Result: - Step 1: Should find production error sanitization code - Step 3: Error response should be generic, not exposing internals
✅ Test 9: Run Package Security Scan¶
Goal: Check for vulnerable dependencies
Steps:
# 1. Scan root package.json
cd .
npm audit
# 2. Scan frontend package.json
cd frontend
npm audit
# 3. Fix automatically (if safe)
npm audit fix
# 4. Check for high/critical issues
npm audit --audit-level=high
Expected Result: - Should show list of vulnerabilities - Fix any high/critical issues
✅ Test 10: Full Integration Test¶
Goal: Verify everything works together
Steps:
# 1. Start backend with proper env vars
cd backend
# Make sure .env has all required variables
python main.py
# 2. Start frontend
cd ../frontend
npm run dev
# 3. Test authentication flow
# - Try to access protected endpoint without token → should fail
# - Login with valid credentials → should work
# - Access protected endpoint with token → should work
# 4. Check browser console for errors
# - No CSP violations
# - No CORS errors (from allowed origins)
# - No authentication errors (when properly authenticated)
Expected Result: - All services start without errors - Authentication works correctly - No security-related errors in console
🎯 Quick Verification Script¶
Run this PowerShell script to test everything at once:
# Security Fixes Verification Script
Write-Host "🔒 Testing Security Fixes..." -ForegroundColor Cyan
Write-Host ""
# Test 1: SSH Keys
Write-Host "Test 1: Checking SSH keys in git..." -ForegroundColor Yellow
$keysInGit = git ls-files | Select-String "key|\.key"
if ($keysInGit) {
Write-Host "❌ FAIL: SSH keys found in git!" -ForegroundColor Red
$keysInGit
} else {
Write-Host "✅ PASS: No SSH keys in git" -ForegroundColor Green
}
# Test 2: Hardcoded secrets
Write-Host "`nTest 2: Checking for hardcoded secrets..." -ForegroundColor Yellow
$hardcoded = Select-String -Path "docker-compose.yml" -Pattern "API_KEY.*:-|POSTGRES_PASSWORD.*:-"
if ($hardcoded) {
Write-Host "❌ FAIL: Hardcoded secrets found!" -ForegroundColor Red
$hardcoded
} else {
Write-Host "✅ PASS: No hardcoded secrets" -ForegroundColor Green
}
# Test 3: Supabase key
Write-Host "`nTest 3: Checking Supabase key..." -ForegroundColor Yellow
$supabaseKey = Select-String -Path "frontend/src/config/supabase.ts" -Pattern "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
if ($supabaseKey) {
Write-Host "❌ FAIL: Hardcoded Supabase key found!" -ForegroundColor Red
} else {
Write-Host "✅ PASS: No hardcoded Supabase key" -ForegroundColor Green
}
# Test 4: Auth bypass
Write-Host "`nTest 4: Checking auth bypass..." -ForegroundColor Yellow
$authBypass = Select-String -Path "backend/middleware.py" -Pattern "ENVIRONMENT.*development.*call_next|development.*unauthenticated"
if ($authBypass) {
Write-Host "❌ FAIL: Auth bypass found!" -ForegroundColor Red
$authBypass
} else {
Write-Host "✅ PASS: No auth bypass" -ForegroundColor Green
}
# Test 5: CSP
Write-Host "`nTest 5: Checking CSP..." -ForegroundColor Yellow
$unsafeCSP = Select-String -Path "backend/main.py" -Pattern "script-src.*unsafe-inline|script-src.*unsafe-eval"
if ($unsafeCSP) {
Write-Host "⚠️ WARNING: Unsafe CSP directives found" -ForegroundColor Yellow
$unsafeCSP
} else {
Write-Host "✅ PASS: CSP is secure" -ForegroundColor Green
}
# Test 6: CORS
Write-Host "`nTest 6: Checking CORS..." -ForegroundColor Yellow
$corsWildcard = Select-String -Path "backend/middleware/cors.js" -Pattern "callback\(null, true\)" -Context 0,2 | Where-Object { $_.Context.PostContext -match "allow.*all|development.*all" }
if ($corsWildcard) {
Write-Host "⚠️ WARNING: CORS may allow all origins in dev" -ForegroundColor Yellow
} else {
Write-Host "✅ PASS: CORS is restricted" -ForegroundColor Green
}
Write-Host "`n✅ Security verification complete!" -ForegroundColor Cyan
📋 Test Results Checklist¶
After running all tests, check off what works:
- SSH keys are ignored by git
- No hardcoded secrets in docker-compose.yml
- Supabase key requires environment variable
- Authentication is always required
- CSP headers are applied (no unsafe-inline/eval for scripts)
- CORS only allows specific origins
- Webhooks require signatures
- Error messages are sanitized in production
- No critical package vulnerabilities
- Full integration test passes
🚨 If Tests Fail¶
- SSH keys in git: Check
.gitignoreand remove files from git history - Hardcoded secrets: Remove defaults from
docker-compose.yml - Auth bypass: Remove development mode bypass code
- CSP issues: Check if frontend needs inline scripts (may need refactoring)
- CORS issues: Verify allowed origins list is correct
💡 Manual Browser Testing¶
- Open DevTools Console:
- Check for CSP violations
- Check for CORS errors
-
Check for authentication errors
-
Test Authentication:
- Try accessing protected routes without login → should redirect/fail
- Login with valid credentials → should work
-
Access protected routes after login → should work
-
Test API Calls:
- Make request without token → should get 401
- Make request with invalid token → should get 401
- Make request with valid token → should work