IMMEDIATE ACTION REQUIRED if deploying from this commit forward:
Fixed 4 critical security vulnerabilities discovered in comprehensive security audit:
-
Exposed Supabase Credentials (CRITICAL)
- Previously hardcoded in
api/submit-score.jsandapi/leaderboard.js - Now requires environment variables (fails fast if not set)
- ACTION: Set
NEXT_PUBLIC_SUPABASE_URLandNEXT_PUBLIC_SUPABASE_ANON_KEYin Vercel
- Previously hardcoded in
-
Hardcoded Admin Password (CRITICAL)
- Previously
'CQgames'hardcoded in source code - Now requires
ADMIN_PASSWORDenvironment variable - ACTION: Set strong random password in Vercel environment variables
- Previously
-
Wildcard CORS Configuration (CRITICAL)
- Changed from
Access-Control-Allow-Origin: *to domain-specific - Now restricted to
https://provably-fair-games.vercel.app - ACTION: Update
vercel.jsonline 39 to match your production domain
- Changed from
-
Unenforced Rate Limiting (CRITICAL)
- Rate limiting flag existed but was never checked
- Now properly enforced (10 submissions per minute per player)
- ACTION: None - automatically enabled when
ENABLE_RATE_LIMITING=true
Supabase URL: https://rmutcncnppyzirywzozc.supabase.co
Supabase Anon Key: sb_publishable_K-KApBISA6IiiNE9CCnjNA_3qhuNg8k
Admin Password: CQgames
Required Actions:
- β Rotate Supabase keys in Supabase Dashboard > Project Settings > API
- β
Set new
ADMIN_PASSWORDin Vercel (never use "CQgames" again) - β Update all environment variables in Vercel Dashboard
- β Redeploy after setting environment variables
- β
See
.env.examplefor complete environment variable documentation
See .env.example file for complete documentation. Required variables:
# Database (REQUIRED)
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_KEY=your-service-key
# Admin Authentication (REQUIRED)
ADMIN_PASSWORD=your-strong-random-password
# Ergo Blockchain for Cron (REQUIRED)
ERGO_SERVER_MNEMONIC=your mnemonic
ERGO_SERVER_ADDRESS=your address
CRON_SECRET=your-secret
# Security Flags (OPTIONAL - defaults shown)
ENABLE_RATE_LIMITING=true
ENABLE_FRAUD_DETECTION=true
VALIDATION_LEVEL=fullSetup Instructions:
- Copy
.env.exampleto.env.localfor local development - Set all variables in Vercel Dashboard > Settings > Environment Variables
- Redeploy after adding variables
Admin Dashboard Protection:
- Dual-layer authentication (frontend + backend)
- Password-based access control
- Session management with automatic expiration
- API key validation on all admin endpoints
- No CAPTCHA - Rate limiting prevents abuse without annoying users
API Security:
- Admin endpoints require
Authorizationheader - 401 Unauthorized response for invalid credentials
- No token in URL (security best practice)
All pages include comprehensive security headers:
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
What These Protect Against:
- X-Content-Type-Options: MIME sniffing attacks
- X-Frame-Options: Clickjacking attacks
- X-XSS-Protection: Cross-site scripting (XSS) attacks
- Referrer-Policy: Information leakage via referrer
- Permissions-Policy: Unauthorized access to device features
Purpose: Prevent spam and abuse without CAPTCHA
Default Limits:
- Score submissions: 10 per minute per player
- Configurable via
ENABLE_RATE_LIMITINGenvironment variable - In-memory tracking (resets on server restart)
Why No CAPTCHA:
- Buggy with VPNs
- Poor user experience
- Can lose good game scores
- Rate limiting is sufficient for this use case
Multi-Layer Validation:
-
Format Validation
- Game ID format (e.g.,
YAH-1234567-abc123) - Game type whitelist (only 6 valid games)
- Score ranges per game
- Data type validation
- Game ID format (e.g.,
-
Game Logic Validation
- Full move/roll/round replay
- Score recalculation from history
- Completion detection
- Rule compliance checks
-
Blockchain Verification
- Ergo block existence validation
- Seed generation verification
- Block height reasonableness checks
- Transaction data validation
-
Fraud Detection
- Statistical analysis (0-100 risk score)
- Pattern detection (bot behavior)
- Player history analysis
- Time-based anomaly detection
Protection Against:
- β Score manipulation
- β SQL injection (Supabase parameterized queries)
- β XSS (React auto-escaping)
- β Invalid data submission
- β Blockchain spoofing
API Endpoints: Domain-restricted for security
Access-Control-Allow-Origin: https://provably-fair-games.vercel.app
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Security Notice:
- Changed from wildcard (
*) to specific domain for security - Prevents CSRF attacks and unauthorized cross-origin requests
- Update
vercel.jsonline 39 to match your production domain - Leaderboard is read-only public data
- Score submission requires blockchain proof (not forgeable)
- Admin endpoints protected by authentication
- Rate limiting prevents abuse
Database Access:
- Supabase Row Level Security (RLS) enabled
- Public read access to leaderboard (transparency)
- Public insert access with server-side validation
- No direct database modification via client
Sensitive Data:
- No personally identifiable information (PII) collected
- Player names are optional (default: "Anonymous")
- No emails, passwords, or payment info
- All blockchain data is public by design
Session Storage:
- Admin credentials stored in
sessionStorage(notlocalStorage) - Automatically cleared when tab closes
- Not persisted across browser sessions
- Manual logout available
Cache Strategy:
| Endpoint | Cache Duration | Reason |
|---|---|---|
/api/leaderboard |
5 minutes | Frequently updated, but not real-time critical |
/api/game/:gameId |
1 hour | Verification data never changes |
/api/submit-score |
No cache | Each submission is unique |
/api/admin |
No cache | Sensitive data, always fresh |
Benefits:
- Reduced server load
- Faster page loads
- Lower bandwidth costs
- Better user experience
| Version | Supported |
|---|---|
| Latest (main branch) | β |
| Previous releases | β |
We only support the latest version. Please update to main branch for security fixes.
How to Report:
- DO NOT open a public GitHub issue for security vulnerabilities
- Open a private vulnerability report on GitHub (if available)
- Or email the repository owner directly (check GitHub profile)
What to Include:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if known)
- Your contact information (for follow-up)
Response Time:
- Acknowledgment: Within 48 hours
- Initial Assessment: Within 1 week
- Fix Timeline: Depends on severity
- Critical: 1-3 days
- High: 1-2 weeks
- Medium: 2-4 weeks
- Low: Best effort
Severity Classification:
- Critical: Authentication bypass, database access, score manipulation at scale
- High: XSS, CSRF, admin bypass, rate limit bypass
- Medium: Information disclosure, denial of service
- Low: Non-sensitive information leakage, UI quirks
Coordinated Disclosure:
- You report the vulnerability privately
- We acknowledge and investigate
- We develop and test a fix
- We deploy the fix to production
- We publicly disclose the issue and credit you (if desired)
Public Disclosure Timeline:
- After fix is deployed to production
- Typically 7-14 days after fix deployment
- Faster for critical issues affecting active users
Safe Gaming:
- Play without providing personal information
- Use anonymous player names if privacy-conscious
- Understand all game data is public on leaderboard
- Don't share admin password if you're an administrator
Verification:
- Always verify suspicious high scores using the verification feature
- Check blockchain proof before trusting scores
- Compare seed generation manually if suspicious
Admin Access:
- Keep admin password secure and private
- Rotate password regularly (requires code change currently)
- Log out after admin sessions
- Don't access admin panel on shared computers
- Review flagged submissions promptly
Monitoring:
- Review validation statistics regularly
- Check fraud patterns by game
- Investigate consistent high-risk players
- Monitor rate limit violations
Code Security:
- Never commit secrets to git
- Use environment variables for configuration
- Keep dependencies updated
- Review code changes for security issues
- Test validation logic thoroughly
Deployment:
- Set environment variables in Vercel dashboard
- Enable HTTPS (automatic with Vercel)
- Review security headers after deployment
- Test admin authentication before going live
Current Security Gaps:
-
No Password Hashing
- Admin password compared as plaintext (constant-time comparison recommended)
- Not a major issue for single-admin system
- Mitigation: Use strong unique password, bcrypt hashing recommended for future
-
Session Storage Only
- Admin session clears on tab close
- Can be annoying for long admin sessions
- Mitigation: Consider localStorage with expiration
-
In-Memory Rate Limiting
- Rate limits reset on server restart (~15 min on Vercel)
- Doesn't persist across multiple instances
- Mitigation: Consider Redis for distributed rate limiting in high-traffic scenarios
-
No Email Verification
- Player names not verified
- Name collisions possible
- Mitigation: Leaderboard shows all matching names
Recently Fixed (2026-01-18):
- β Admin password now in environment variable (not hardcoded)
- β Supabase credentials no longer hardcoded (fail-fast validation)
- β CORS changed from wildcard to domain-specific
- β Rate limiting now actually enforced (was configured but not used)
Completed Enhancements:
- β Admin Authentication (Completed - Week 7)
- β Security Headers (Completed - Week 7)
- β Rate Limiting (Completed - Week 7)
- β Comprehensive Validation (Completed - Week 6)
- β Admin Password in Environment Variable (Completed - 2026-01-18)
- β Credential Security Hardening (Completed - 2026-01-18)
- β CORS Security Restriction (Completed - 2026-01-18)
- β Rate Limiting Enforcement (Completed - 2026-01-18)
Future Enhancements (Priority Order):
- π Password Hashing with bcrypt (High priority - prevents credential exposure)
- π Persistent Rate Limiting (Redis integration for distributed systems)
- π Audit Logging (Track all admin actions with timestamps)
- π Two-Factor Authentication (For admin access)
- π IP-Based Rate Limiting (More granular control)
- π Content Security Policy Header (Additional XSS protection)
- π Automated Security Scanning (CI/CD integration)
- π Automated Credential Rotation (Periodic password rotation)
For security concerns or questions:
- GitHub Issues: https://github.com/cannonQ/provably-fair-games/issues (for non-sensitive questions)
- Private Reports: Use GitHub's private vulnerability reporting
- Email: Check repository owner's GitHub profile
Last Updated: 2026-01-18