================================================================================ SCREECHVR: FINAL SECURITY RESEARCH CORRECTION, VALIDATION & COMPLETE TEXT BUNDLE ================================================================================ 1. COVER AND SCOPE ================================================================================ Project name: ScreechVR (Voideration Anti-Cheat) Research date: 2026-10-29 (final correction pass) Purpose: Final correction, validation, and consolidation pass. Resolves inconsistencies, verifies findings against actual project and official documentation, produces one self-contained text file for independent review. No implementation was performed. No project files were modified. No services were deployed. No production data was changed. No credentials were reproduced. Research-only phase. Awaiting explicit approval before any code is written. Budget constraint: €0 additional monthly spend. Game-server hosting already handled (Photon Cloud relay, not authoritative). No new paid services. ================================================================================ 2. EXECUTIVE FINDINGS ================================================================================ Most important verified findings: 1. ScreechVR uses Unity 2021.3 LTS, Photon PUN 2 + Voice, PlayFab, Meta/Oculus SDK, Cloudflare Worker. IL2CPP for Quest builds. No dedicated authoritative game server. Existing server infrastructure is relay-only (Photon Cloud) or client-hosted (Master Client). Game-server hosting being "handled" does not mean authoritative gameplay exists. 2. Currency flow: Oculus_Login.cs AddCurrency/RemoveCurrency update local _currency before server call. PlayFab AddUserVirtualCurrency accepts client-specified amount (validates session, not amount). CONDITIONAL: depends on PlayFab title settings (client access). If enabled, CRITICAL vulnerability. Server-authoritative grants recommended regardless. 3. Moderator status stored in PlayFab UserData "Moderator" key. PlayFab UserData is client-writable by default. Check_Mod.cs sets AccountPref after 5s timeout. CONDITIONAL: verify in PlayFab dashboard. If client-writable, CRITICAL. 4. Bans enforced client-side only: KickIfBanned polls GetAccountInfo every 5s; Kick_Player triggers Application.Quit. Modified client can ignore both. Server-side enforcement via Photon custom auth is the fix (connect-time rejection). 5. No movement validation: Player.cs locomotion all client-side. No server validation. Movement exploits can only be detected heuristically, not prevented (no dedicated server). 6. Master client is a player, not a server. AutomaticallySyncScene=true allows master to force scene loads on all clients. 7. No anti-cheat scripts exist. No server-side validation of movement, position, or score. 8. Photon RPCs lack ownership checks, param validation, rate limits (ThusterController floods, Flash_Light held-button floods). 9. Null crashes throughout (PlayerSpawner, Hand_Physic, Monster_Track, etc.) unguarded. 10. AppEntitlementCheck logs only, does not quit on failure. 11. Photon auth: Photon custom auth delegates to backend (server-to-server). Worker receives Photon auth token (from GetPhotonAuthenticationToken). Worker validates via PlayFab API using its own credentials. PlayFab session ticket is NOT needed as custom auth param. CORRECTED: earlier claim that client MUST send session ticket was wrong. 12. Meta attestation: official docs now accessible. Token valid 24h by default (configurable). Server must validate: exp (within 24h), nonce (one-time use), timestamp (recent), app_integrity_state (StoreRecognized), package_cert_sha256_digest (matches), device_integrity (Advanced or Basic). Rate limits: 100 req/hour, 200 req/day per device. security_update_pending_days only available if device_state is Advanced or Basic. 13. Meta User Verification: getUserProof returns proof of account control. Server validates nonce (server-generated, one-time use). DIFFERENT from App Attestation challenge_nonce. User Verification proves identity; App Attestation proves device/app integrity. NOTE: "hardware-bound" is inaccurate. Meta identity proves account control, not device binding. 14. Photon pricing (VERIFIED from official page): free tier 20 CCU (dev only). 100 CCU = $95/12mo (one-time). 500 CCU = $95/mo. 1000 CCU = $185/mo. 2000 CCU = $370/mo. Premium Cloud = $0.29/CCU, min $580/mo. Voice separate. PUN 2 in maintenance/LTS mode. 15. Heartbeat cost: 10s = 8,640 req/player/day. At 100 CCU = 864,000 req/day (exceeds free tier). 30s = 2,880 req/player/day. At 100 CCU = 288,000 req/day (exceeds free tier). 5-min = 288 req/player/day. At 100 CCU = 28,800 req/day (within free tier). Recommendation: 30s request (no D1 write) + 5-min D1 write. Or KV for session state. Highest-severity unresolved issues: 1. PlayFab UserData "Moderator" key writability (CRITICAL if client-writable). 2. CloudScript/Azure Functions deployment status (unknown). 3. Meta attestation API availability to ScreechVR (docs accessible, eligibility unverified). 4. Photon custom auth configuration (dashboard not inspected). 5. PlayFab PurchaseItem price validation (assumed, unverified). Recommended next step: Verify the 5 critical items above (requires dashboard access), then begin Stage 1 implementation after user approval. ================================================================================ 3. PROJECT AND RESEARCH COVERAGE ================================================================================ Source files inspected: - Assets/Scripts/Oculus_Login.cs (auth, currency, ban, MOTD, title data, inventory) - Assets/Scripts/ScreechApi.cs (worker HTTP) - Assets/Scripts/PhotonVRManager.cs (networking, rooms, cosmetics, gun) - Assets/Scripts/PlayerSpawner.cs (spawn/despawn) - Assets/Scripts/UsernameValidator.cs (content creator check) - Assets/Scripts/AppEntitlementCheck.cs (Oculus entitlement, log only) - Assets/Scripts/KickIfBanned.cs, Kick_Player.cs (ban/kick) - Assets/Scripts/LevelSelect.cs, MapLoader.cs, sceneyessss.cs (scene loading) - Assets/Scripts/Gamemode_System.cs, GamemodeManager.cs, Gamemode_.cs, DeployGamemode.cs - Assets/Scripts/GetCosmetics.cs, SecondaryCosmetics.cs, BuyCosmetic.cs, Cosmetic_Yes.cs - Assets/Scripts/TagManager.cs, TagPlayer.cs, TagLeaderboard.cs - Assets/Scripts/BestJumpscare.cs (collider kill) - Assets/Scripts/NewGorillaLocomotionScripts/Player.cs (locomotion) - Assets/Scripts/Hand_Physic.cs (grab/physics) - Packages/manifest.json (SDKs) - Assets/Resources/GorillaPrefabs/Gorilla Rig.prefab Research documents reviewed: - research/ (27 reports + README + FINAL_RESEARCH_SUMMARY) - research/FINAL_SECURITY_ARCHITECTURE/ (26 deliverables) - docs/screechvr-technical-map-2026-10-28.md - docs/voideration-screechvr-architecture.md - docs/voideration-anticheat-research.md - docs/voideration-anticheat-review.md - research/QUEST_MODIFICATION_THREAT_CATALOG.md - SHARED-MEMORY.md, AGENTS.md Claims checked against official documentation: - PlayFab: AddUserVirtualCurrency, PurchaseItem, LoginWithCustomID, GetPhotonAuthenticationToken, BanUsers, GetTitleData, GetUserData/UpdateUserData - Photon: custom authentication response codes (0=incomplete, 1=success, 2=failure, 3=invalid params), PUN 2 maintenance mode, pricing (free 20 CCU, 100 CCU $95/12mo, 500 CCU $95/mo, 1000 CCU $185/mo) - Cloudflare: Workers free tier (100k req/day), D1 free tier (5GB, 5M reads/day, 100k writes/day), KV free tier - Meta: Attestation API (now accessible, full docs retrieved), User Verification (ps-ownership, partially accessible), device ban (server-to-server) - OWASP: API Security Top 10 2023, Cryptographic Storage Cheat Sheet Items that could not be accessed: - PlayFab dashboard (CloudScript, UserData permissions, PurchaseItem config, ban enforcement) - Photon dashboard (custom auth config, anonymous client setting, dev/prod app IDs) - Meta developer portal (User Verification full docs, attestation eligibility) ================================================================================ 4. Photon authentication correction ================================================================================ Token distinctions (CRITICAL - not interchangeable): - PlayFab Session Ticket: issued by PlayFab on login, used for PlayFab API calls and worker /redeem. Lifetime: session duration (hours). Verified by PlayFab (GetAccountInfo). - Photon Custom Auth Token: issued by PlayFab GetPhotonAuthenticationToken, used for Photon connection. Lifetime: short (minutes). Verified by Photon's servers (server-to-server call to custom auth URL). - Meta Oculus ID: identifier from Oculus Platform SDK. Used as PlayFab CustomId. Proves nothing by itself; must be verified via Meta User Verification. - Meta User Proof: one-time proof of account control (getUserProof). Verified server-side with Meta. NOT currently used in ScreechVR. - Meta Attestation Token: device/app integrity token. Verified server-side with Meta. UNVERIFIED availability for ScreechVR. Correct authentication flow (PlayFab Photon integration): 1. Client: Oculus Core.Initialize + Users.GetLoggedInUser -> Oculus ID + username. 2. Client: PlayFab LoginWithCustomID (Oculus ID, CreateAccount=true) -> PlayFab session ticket. 3. Client: PlayFab GetPhotonAuthenticationToken (photonAppId) -> Photon custom auth token. 4. Client: Photon ConnectUsingSettings with custom auth params (Photon token as auth param). 5. Photon server: calls custom auth URL (worker) with auth params (server-to-server). 6. Worker: receives Photon token. Validates by calling PlayFab API using its own credentials. Worker can call PlayFab GetAccountInfo to verify the account exists and is not banned. Worker does NOT need the PlayFab session ticket as a custom auth param. 7. Worker: checks ban status via PlayFab (using worker's own admin key), returns allow/deny + UserId. 8. Photon enforces result. Client cannot bypass. CORRECTED: Earlier claim that client MUST send PlayFab session ticket as custom auth param was incorrect. The worker receives the Photon auth token (from GetPhotonAuthenticationToken). The worker validates it via PlayFab's API using its own credentials. The client does not need to send the PlayFab session ticket separately. PlayFab session ticket is for PlayFab API calls (/redeem, inventory, etc.), not for Photon auth. PlayFab Photon integration (standard flow, from official docs): - PlayFab provides GetPhotonAuthenticationToken which returns a token. - Photon's custom auth URL receives this token (server-to-server). - The backend at that URL validates the token with PlayFab. - PlayFab's documented endpoint: https://.playfabapi.com/photon/authenticate - If using a custom worker instead, the worker receives the Photon token and must validate it via PlayFab's API (using its own admin key). The worker cannot validate the Photon token independently unless PlayFab provides a verification endpoint. - PlayFab GetAccountInfo can verify the account exists and retrieve ban status. The worker uses its own PlayFab admin credentials, not the client's session ticket. Custom Worker authentication (if used): - Worker receives Photon token from Photon's servers (server-to-server, not client). - Worker validates token by calling PlayFab API (GetAccountInfo) using its own admin key. - Worker checks ban status via PlayFab (GetAccountInfo or ban list). - Worker returns allow/deny + UserId to Photon. - Credential exposure: Photon token is sent over HTTPS (encrypted). Worker logs should not include the token. URL params may be logged by proxies; use POST body for sensitive data. Photon custom auth response codes (verified from official docs): - ResultCode 0: incomplete (multi-step auth). - ResultCode 1: success (allow). - ResultCode 2: failure (deny). - ResultCode 3: invalid parameters. - Photon enforces: deny on failure, allow on success. Configuration uncertainties (dashboard not inspected): - Is custom auth configured in Photon dashboard? - Is "Allow anonymous clients" disabled? - Is the auth URL pointing to the worker or PlayFab's /photon/authenticate? - Are dev and prod app IDs separate? - Does the client include the Photon token (not session ticket) in auth params? Failure/replay behavior: - Missing credentials: Photon denies connection (if custom auth configured). - Invalid token: Photon denies connection. - Expired session: Photon token expired -> worker returns deny. - Revoked session: worker must track session IDs and reject revoked ones (not currently implemented). - Banned account: worker checks ban status (PlayFab GetAccountInfo) -> deny. - Anonymous client: if "Allow anonymous clients" enabled, client can connect without auth (VULNERABILITY). - Backend timeout: Photon's behavior on timeout is UNVERIFIED. May allow or deny. - Backend outage: if worker is down, Photon custom auth fails -> Photon may deny or allow (depends on config). Tests required: - Invalid Photon credentials -> connection denied. - Banned user -> connection denied. - Anonymous client -> connection denied (if anonymous disabled). - Expired session -> connection denied. - Backend timeout -> connection denied (verify Photon behavior). - Old client -> connection denied (version check). ================================================================================ 5. Meta identity verification correction ================================================================================ Current flow (verified from Oculus_Login.cs): Oculus ID -> PlayFab LoginWithCustomID (no proof verification) -> PlayFab session ticket. VULNERABILITY: Client provides Oculus ID without proof. Modified client can claim any Oculus ID. Proposed fix (not implemented): 1. Client: Oculus Core.Initialize + Users.GetLoggedInUser -> Oculus ID + username. 2. Client: Request Meta User Proof (getUserProof) with server-generated nonce. - Server generates nonce, sends to client. - Client calls getUserProof(nonce). - Meta returns proof containing the nonce. 3. Client: Send proof + Oculus ID to backend (worker). 4. Backend: Verify proof with Meta's servers (server-to-server). - Backend sends proof to Meta verification endpoint. - Meta verifies nonce matches, returns verified identity. 5. Backend: If verified, link/create PlayFab account (LoginWithCustomID with verified Oculus ID). 6. Backend: Issue session token (JWT) bound to verified identity. CRITICAL DISTINCTION (corrected wording): - Meta User Verification (getUserProof): proves user controls the Meta account. The proof is tied to the Meta account, not to device hardware. "Hardware-bound" is inaccurate - the proof verifies account control, not device binding. The Oculus ID is associated with a Meta account, but the proof verifies that the current user controls that account. - Meta App Attestation (GetIntegrityToken): proves device/app integrity. Uses server-generated challenge_nonce. One-time use. - These are DIFFERENT APIs with DIFFERENT nonce mechanisms. Do not confuse them. SDK and permission uncertainties: - Unity 2021.3.32f1: Meta SDK version compatibility unknown. - Required permissions: Data Use Checkup (User ID, User Profile, Device Ban). - Account migration: existing players need migration path. - Duplicate account handling: same Meta ID, multiple PlayFab accounts. Security boundaries: - Meta identity verification proves user controls the Meta account. - Does NOT prove game integrity, no cheating, legitimate gameplay. - Identity is one layer. Must combine with server-side validation and detection. Tests required: - Invalid Meta proof -> login denied. - Replay of Meta proof -> login denied (nonce must be one-time). - Account linking without proof -> login denied. - Stale proof (expired nonce) -> login denied. ================================================================================ 6. Meta attestation correction ================================================================================ Current documented API behavior (from official Meta docs, fetched 2026-10-29): API: ovr_DeviceApplicationIntegrity_GetIntegrityToken(const char *challenge_nonce) - Platform: Android only. Quest 2, Quest Pro, Quest 3, Quest 3S. - Requires: Platform SDK v55+, Meta Horizon OS v55+. - Wi-Fi required (attestation server communication). Flow: 1. Server generates challenge_nonce (Base64URL, 22-172 chars, cryptographically random, one-time use). 2. Client calls GetIntegrityToken(challenge_nonce) -> Meta attestation server collects security signals -> generates attestation token. 3. Client sends token to app server. 4. App server sends token + access_token to Meta verification endpoint: https://graph.oculus.com/platform_integrity/verify?token=&access_token= 5. Meta returns claims (success) or error (invalid signature, token expired). Token claims (Base64URL-encoded): - request_details: exp (expiration, default 24h), nonce (must match challenge_nonce), timestamp (UTC seconds, token creation time). - app_state: app_integrity_state (StoreRecognized/NotRecognized/NotEvaluated), package_cert_sha256_digest (SHA-256 of signing cert), package_id, version. - device_state: device_integrity_state (Advanced/Basic/NotTrusted), unique_id (changes every 30 days), security_update_pending_days (only if Advanced/Basic). Token validation (server must check): - exp: within 24 hours (default, configurable in dashboard). This is the token's expiration time. - nonce: matches challenge_nonce (one-time use, prevent replay). This is the replay protection mechanism. - timestamp: recent (within a few minutes). This is the freshness check, separate from exp. - app_integrity_state: StoreRecognized (legitimate installation). - package_cert_sha256_digest: matches expected signing cert hash. - device_integrity_state: Advanced or Basic (NotTrusted = unlocked bootloader or invalid OS). Replay protection: - challenge_nonce must be unique, cryptographically random, used only once. - Server stores nonce, verifies returned nonce matches, then discards. - Nonce length: 22-172 characters (Base64URL). Rate limits: - 100 requests/hour per device. - 200 requests/day per device. - Token caching recommended (reuse within validity period, less than 24h). security_update_pending_days: - Number of days since oldest public security patch missing. - 0 = fully up to date. - Only available if device_state is Advanced or Basic. - Use caution: aggressive use may lock out slow-updating users. device_integrity_state meanings (from official docs): - Advanced: bootloader locked, valid Android OS, no signs of system compromise. - Basic: bootloader locked, valid Android OS, but some integrity checks failed (possibly rooted). - NotTrusted: bootloader unlocked, or invalid Android OS image. Device ban (server-to-server): - Uses unique_id (changes every 30 days) and ban_id (persistent). - Ban duration: 0-52560000 minutes (100 years max). - Requires Data Use Checkup approval. - Ban enforcement on server side (check device_ban section in token claims). API configuration (dashboard): - Device Integrity State Bypass: enabled by default (testing devices always Advanced). - Token Expiration Duration: default 24h, configurable (shorter = more secure, more API calls). Best practices (from official docs): - Validate attestation tokens server-side only. - Handle errors securely (exponential backoff, treat failure as NotTrusted). - Validate token securely (exp, nonce, timestamp, app_integrity_state, package_cert, device_integrity). - Include unique elements in challenge_nonce (cryptographically secure random, transaction ID). - Bind sensitive requests to challenge_nonce (hash critical request params + nonce). - Opt for account limitations instead of binary blocking (allow with restrictions). What remains unverified for ScreechVR: - API availability to all Quest developers vs gated (Data Use Checkup required for device ban). - Whether ScreechVR's Meta app has the required permissions (User ID, User Profile, Device Ban). - Unity 2021.3.32f1 + Platform SDK v55+ compatibility. - Whether attestation works for sideloaded builds (app_integrity_state = NotRecognized for sideloaded). - Eligibility requirements (may require Meta approval). Handling policy (proposed): - Trusted (Advanced, StoreRecognized): normal access. - Suspicious (Basic): flag + increased monitoring, allow with restrictions. - Untrusted (NotTrusted or NotRecognized): restrict sensitive actions (no purchases, no leaderboard submissions), flag for review. - Unsupported (older device, SDK < v55): allow with warning (log for analysis). - Unavailable (service outage, network failure): allow with flag (service failure, not user's fault). Do not block. - Inconclusive (errors, missing claims): flag + manual review. Do not auto-ban. ================================================================================ 7. PlayFab and privilege correction ================================================================================ Currency API findings (VERIFIED from source code): - Oculus_Login.cs: AddCurrency(int amount) calls PlayFab AddUserVirtualCurrency with client-specified amount. - PlayFab validates session ticket but NOT amount. Client can grant arbitrary currency. - BuyCosmetic.cs checks local _currency >= Price before calling PlayFab PurchaseItem. - PlayFab PurchaseItem validates price server-side against catalog (STRONG EVIDENCE, verify in dashboard). - Currency_Code = "HC". _currency is client-held int. CONDITIONAL: Whether clients can actually call AddUserVirtualCurrency depends on PlayFab title settings (client access). If client access is disabled, only server-side calls work (and the vulnerability doesn't exist). If enabled, it's critical. VERIFY in PlayFab dashboard. Moderator permissions (UNVERIFIED): - Oculus_Login.cs: CreateKeyIfNot creates "Moderator"="FALSE" in PlayFab UserData. - PlayFab UserData is client-writable by default (STRONG EVIDENCE from PlayFab docs). - If client-writable, any client can set "Moderator"="TRUE" -> self-promotion. - Check_Mod.cs sets AccountPref = Moderator if UserData "Moderator" == "TRUE". - Mod_Toggle.cs opens ModMenu if DefaultQueue == "MODDED". - CRITICAL: Verify PlayFab UserData write permissions in dashboard. If client-writable, immediate critical vulnerability. Purchase and inventory checks: - PlayFab PurchaseItem validates price server-side against catalog (STRONG EVIDENCE, verify). - Client gates on local balance (cosmetic issue, not security). - Inventory: GetUserInventory (server-side). Cosmetic ownership should be verified server-side. Ban enforcement: - PlayFab bans are server-side (admin API). Ban status checked via GetAccountInfo. - KickIfBanned polls every 5s (client-side, ignorable). - No server-side kick enforcement (requires Photon custom auth ban check). Other unresolved PlayFab flows: - CloudScript/Azure Functions: none found in repo. Verify in dashboard. - SpokesSigmaIAP receipt validation: not fully read. - GDH leaderboard submission path: unknown anti-cheat. - ATM_TAB/Atm_Manager: not deeply read. - Leaderboard validation: unknown. ================================================================================ 8. Backend and database cost correction ================================================================================ Current pricing sources (verified 2026-10-29): Cloudflare: - Workers: free 100k req/day. Paid: $5/mo + $0.50/million requests. - D1: free 5GB, 5M reads/day, 100k writes/day. Paid: $0.001/100k reads, $1.00/1M writes. - KV: free 100k reads/day, 1k writes/day. Paid: $0.50/million reads. - R2: free 10GB storage, 1M reads/mo, 1M writes/mo. Paid: $0.015/GB/mo. - Pages: free (unlimited static sites). PlayFab: free tier (limits vary, verify in dashboard). Photon (VERIFIED from official pricing page 2026-10-29): - Free tier: 20 CCU (development only, 60 GB traffic/month, capped, no burst). - 100 CCU: $95 one-time (12-month term, ~$8/mo averaged). 0.3 TB traffic. Capped, no burst. - 500 CCU: $95/mo. 1.5 TB traffic. CCU burst included. - 1000 CCU: $185/mo. 3.0 TB traffic. CCU burst. - 2000 CCU: $370/mo. 6.0 TB traffic. CCU burst. - Premium Cloud: $0.29/CCU invoiced, min $580/mo (2000 CCU + 6 TB). Up to 50,000 CCU. - Enterprise: custom (unlimited CCU, SLA, dedicated servers, server-authoritative plugins). - Traffic overage: $0.05/GB (Europe/Canada/US) or $0.10/GB (Asia/etc.). - Voice is separate (Photon Voice has its own pricing). - 1 CCU ~ 20 DAU ~ 400 MAU (rule of thumb). - Downgrade/upgrade anytime. Unused fees credited. - PUN 2 is in maintenance/LTS mode. Photon recommends Fusion for new projects. Workload calculations: - 10s heartbeat: 6 req/min = 360 req/hour = 8,640 req/day per player. At 50 CCU: 432,000 req/day (exceeds free tier 100k/day). At 100 CCU: 864,000 req/day (exceeds free tier 8.6x). - 30s heartbeat: 2 req/min = 120 req/hour = 2,880 req/day per player. At 50 CCU: 144,000 req/day (exceeds free tier 1.4x). At 100 CCU: 288,000 req/day (exceeds free tier 2.9x). - 60s heartbeat: 1 req/min = 60 req/hour = 1,440 req/day per player. At 50 CCU: 72,000 req/day (within free tier). At 100 CCU: 144,000 req/day (exceeds free tier 1.4x). - 5-min heartbeat: 0.2 req/min = 12 req/hour = 288 req/day per player. At 50 CCU: 14,400 req/day (within free tier). At 100 CCU: 28,800 req/day (within free tier). At 1000 CCU: 288,000 req/day (exceeds free tier 2.9x). D1 write calculations: - Every heartbeat write (30s): 2,880 writes/day per player. At 50 CCU: 144,000 writes/day (exceeds free tier 100k/day). At 100 CCU: 288,000 writes/day (exceeds 2.9x). - Every 5-min write: 288 writes/day per player. At 50 CCU: 14,400 writes/day (within free tier). At 100 CCU: 28,800 writes/day (within free tier). At 1000 CCU: 288,000 writes/day (exceeds 2.9x). Alternative heartbeat designs: - 30s request to worker (no D1 write): session liveness tracked in KV (eventual consistency). - 5-min D1 write: session persistence (strong consistency). - Batch telemetry: send every 30s instead of per-event. - Periodic persistence: write to D1 every 5 min, not every heartbeat. - Use KV for session state (eventual consistency acceptable for liveness). Costs at requested CCU scenarios: - 50 CCU: $1-2/mo (domain only, all free tiers). Photon free tier (20 CCU) EXCEEDED -> upgrade to $95 one-time (12-month term). - 100 CCU: $5-16/mo (Cloudflare) + $95 one-time/12mo (Photon). Total: $5-16/mo + $95/yr. - 500 CCU: $16-33/mo (Cloudflare) + $95/mo (Photon) = $111-128/mo. - 1000 CCU: $16-40/mo (Cloudflare) + $185/mo (Photon) = $201-225/mo. - 5000 CCU: $65-130/mo (Cloudflare) + $370+/mo (Photon) = $435+/mo. Key insight: Photon is the cost bottleneck. Cloudflare scales cheaply. PlayFab scales with usage. Free-tier limits and what happens when exceeded: - Cloudflare: 429 Too Many Requests. Backend auth fails closed (deny connections). - PlayFab: API calls fail. Client gets error. Game may not function. - Photon: connection refused. Game unplayable (no multiplayer). ================================================================================ 9. Multi-layer architecture review ================================================================================ 13 layers (independent where possible): 1. Meta User Verification (platform) - identity proof. If bypassed: attacker claims any Oculus ID. 2. Meta Entitlement (platform) - app ownership. If bypassed: unentitled clients stay. 3. Meta Attestation (platform, optional) - device/app integrity. If bypassed: no device integrity signal. 4. PlayFab Auth (backend) - account identity. If bypassed: attacker creates accounts with arbitrary IDs. 5. Photon Custom Auth (network) - room admission. If bypassed: banned/invalid players connect. 6. Worker session validation (worker) - session validity. If bypassed: stale/revoked sessions work. 7. Backend authorization (worker) - API permissions. If bypassed: attacker calls any API. 8. Server-side economy (PlayFab/worker) - currency/inventory. If bypassed: attacker mints currency. 9. Server-side bans (PlayFab) - enforcement. If bypassed: banned player returns. 10. Detection engine (worker) - behavioral flags. If bypassed: suspicious behavior not flagged. 11. Rate limiting (worker/Cloudflare) - abuse prevention. If bypassed: attacker floods endpoints. 12. Audit logging (worker) - accountability. If bypassed: no evidence trail. 13. Dashboard security (worker) - admin protection. If bypassed: unauthorized admin access. Common-mode failures: - If Meta platform compromised: layers 1-3 fail. Layers 4-13 still function. - If PlayFab compromised: layers 4, 8, 9 fail. Layers 1-3, 5-7, 10-13 still function. - If worker compromised: layers 6, 7, 10, 11, 12, 13 fail. Layers 1-5, 8, 9 still function. - If Photon compromised: layer 5 fails. Layers 1-4, 6-13 still function. Attack-to-defense matrix: see research/ANTI_CHEAT_PREVENTION_DETECTION_MATRIX.md. ================================================================================ 10. Photon RPC and gameplay authority findings ================================================================================ Actual enforcement points: - Photon Cloud: relays RPCs, no param validation, no rate limiting, no game logic. - Photon Master Client: player with flag, controls room properties and scene sync. Untrusted. - Worker: can enforce rate limits on Worker API calls only (not Photon RPCs). - PlayFab: can enforce bans, inventory, currency (server-side). - Dedicated server: not available (v2+). Game-server hosting is "handled" but this is relay-only (Photon Cloud), not authoritative. Client-controlled state (cannot be prevented without dedicated server): - Movement/position (Player.cs, locomotion). - Tag/infection state (TagPlayer.cs, TagManager.cs RPCs). - Score/leaderboard submissions (GDH leaderboard). - Cosmetic equip (GetCosmetics.cs, Photon props). - Game state (Gamemode_System.cs, CurrentMode). What can be prevented (server-side): - Currency minting (move grants to worker/CloudScript). - Moderator spoof (server-side role verification). - Ban bypass (Photon custom auth ban check). - Cosmetic spoof (backend inventory check). - Version mismatch (title data + custom auth). What can only be detected (heuristic, not prevention): - Movement exploits (speed, teleport, fly). - RPC floods (rate limit + flag). - Tag/Infection spoof (flag non-tagger RPCs). - Leaderboard faking (flag anomalies). - Master client abuse (log + flag). Recommended short-term (v1): Backend validation + heuristic detection + manual review. Recommended long-term (v2+): Dedicated authoritative server for movement, scoring, bans. ================================================================================ 11. Provider and authentication comparison corrections ================================================================================ Revised findings: - Meta User Verification: strongest identity proof (account control, NOT hardware-bound). UNVERIFIED availability. - PlayFab: good for auth/inventory/bans. Custom ID login is client-provided (not proof). Add Meta User Verification. - Firebase Auth: good Unity support, free tier, but adds complexity. No clear benefit over PlayFab for Quest game. - Supabase Auth: free tier pauses after 7 days inactivity. Not suitable for production without paid plan. - Nakama: best open-source option. Authoritative multiplayer. High migration cost (20-30 weeks). Hosting $5-50/mo. - Appwrite/PocketBase: limited Unity support. Not recommended. - Keycloak/Ory/Authentik: heavy, overkill for solo dev. Self-hosted ops burden. - Auth0/Clerk: good free tiers (7.5k-10k MAU). MAU limits. Not Quest-specific. - AWS Cognito: 50k MAU free. Complex, AWS lock-in. - Cloudflare: good for API/backend. No native game-user identity. Use with PlayFab. Recommended: Meta User Verification + PlayFab (identity) + Cloudflare worker (API/backend) + Photon (networking). No new provider needed for v1. Corrected free-tier limitations: - Cloudflare Workers: 100k req/day (free). Exceeded -> 429 or $5/mo paid. - Cloudflare D1: 5GB, 5M reads/day, 100k writes/day (free). Exceeded -> paid. - PlayFab: free tier limits (verify in dashboard). - Photon: free tier 20 CCU (dev only). Exceeded -> $95/12mo for 100 CCU. - Firebase: Spark plan (free, no credit card). Blaze (pay-as-you-go) for functions. - Supabase: free tier pauses after 7 days inactivity. ================================================================================ 12. Corrected final architecture ================================================================================ Text-based architecture diagram: [Quest Client (Unity/IL2CPP)] | Oculus Auth (Core.Initialize + Users.GetLoggedInUser) | Meta User Proof (getUserProof, server-generated nonce) | PlayFab Login (LoginWithCustomID, verified Oculus ID) | PlayFab Session Ticket | Photon Connect (Custom Auth -> Cloudflare worker) | Heartbeat (every 30s -> worker) | Telemetry (movement samples, events -> worker) v [Cloudflare Worker (trusted)] | /validate-session (Meta proof + PlayFab ticket + ban check) | /heartbeat (session liveness, duplicate detection) | /report-flag (telemetry -> detection rules) | /ban-check (real-time ban status) | /redeem (existing, PlayFab ticket required) | /motd (existing, public) | /updateplayers (existing, public, rate-limited) v [D1 Database (SQLite)] sessions, players, flags, bans, audit_log, ccu_snapshots, webhooks, detection_rules, evidence v [PlayFab (trusted backend)] Auth, inventory, currency, bans, title data, leaderboards, user data v [Photon Cloud (semi-trusted relay)] Rooms, RPCs, sync, voice. Master client = player. Custom auth -> worker (server-to-server) v [Cloudflare Pages (dashboard)] React + Tailwind + shadcn/ui. Auth: email+password+TOTP. JWT. RBAC. Reads from worker API only. Sources of truth: - Player identity: PlayFab (verified Oculus ID). - Session validity: Worker (PlayFab ticket + session tracking). - Ban status: PlayFab (server-side). - Currency balance: PlayFab (server-side after fix). - Inventory/cosmetics: PlayFab (server-side). - Movement/position: Client (untrusted, heuristic detection only). - Game state (scores, kills): Client (untrusted). - Room state: Photon (relay, master client untrusted). - Moderator status: PlayFab (server-side after fix). - CCU: Worker (heartbeat-based). - Audit log: Worker D1 (append-only). Failure behavior: - PlayFab down: fail closed for auth (deny new connections), fail open for gameplay (existing sessions continue), bans still enforced from cache. - Worker down: Photon custom auth fails -> Photon denies connections (fail closed). Existing sessions continue. - D1 down: audit log/flags delayed, core auth still works (worker validates via PlayFab directly). - Photon down: game unplayable (no multiplayer). Single-player not affected. Security guarantees (current vs proposed vs tested): - Currency cannot be minted: CURRENT=no (client-trusted), PROPOSED=yes (server-side), TESTED=no. - Bans cannot be bypassed: CURRENT=no (client-side), PROPOSED=yes (custom auth), TESTED=no. - Moderator status cannot be spoofed: CURRENT=unknown (verify UserData), PROPOSED=yes (server-side), TESTED=no. - Cosmetics verified against inventory: CURRENT=no, PROPOSED=yes, TESTED=no. - Version enforcement: CURRENT=partial (title data, client can ignore), PROPOSED=yes (custom auth), TESTED=no. - Movement exploits: CURRENT=no, PROPOSED=detect only (heuristic), TESTED=no. - RPC floods: CURRENT=no, PROPOSED=rate limit, TESTED=no. ================================================================================ 13. Threat-to-defense matrix ================================================================================ (See research/ANTI_CHEAT_PREVENTION_DETECTION_MATRIX.md for full 18-row matrix.) Key threats and defenses: 1. Modified APK -> Meta entitlement + version enforcement + server-side ban check. 2. Client-trusted currency -> Move grants to server-side (worker/CloudScript). CONDITIONAL: depends on PlayFab title settings. 3. Moderator spoof -> Server-side role verification (PlayFab server data). CONDITIONAL: depends on UserData writability. 4. Ban evasion -> Photon custom auth ban check on connect + KickIfBanned (supplementary). 5. Movement exploits -> Heuristic detection (speed/teleport flags) + manual review. NOT auto-ban. 6. Cosmetic spoof -> Backend inventory verification + flag mismatch. 7. Leaderboard faking -> Server-side score validation or remove from leaderboard. 8. IAP bypass -> PlayFab PurchaseItem validates price server-side + server-side balance check. 9. Tag/Infection spoof -> Rate limit + ownership check + flag non-tagger RPCs. 10. Master client abuse -> Minimize master authority, move room state to backend. 11. RPC flood -> Per-player rate limits + flag. 12. Null crashes -> Guard null refs + server-side crash detection. 13. Duplicate session -> Heartbeat-based detection + kick older. 14. Version spoof -> Title data + custom auth version check. 15. Alt account ban evasion -> Hardware + IP overlap detection. 16. Attestation failure -> Flag + manual review. Do not auto-ban. 17. Frida/injection -> Server-side enforcement limits blast radius. Client detection = low-conf flag. 18. Memory modification -> Server-side validation of all valuable state. ================================================================================ 14. Implementation roadmap ================================================================================ Stage 0: Close research gaps (1 week) - Verify PlayFab UserData "Moderator" writability. - Verify CloudScript/Azure Functions deployment. - Verify PlayFab PurchaseItem price validation. - Verify Meta attestation availability (if possible). - Verify Photon custom auth configuration. - Effort: 1 week. Risk: low. Stage 1: Backend foundation (2-3 weeks) - Cloudflare worker extensions: /validate-session, /heartbeat, /report-flag, /ban-check. - D1 database schema. - Photon custom auth integration. - PlayFab integration: validate session tickets, check bans. - Acceptance: Photon connection fails for banned/invalid sessions; heartbeat tracks CCU. Stage 2: Detection (2-3 weeks) - Movement telemetry collection. - Rules S-001, S-002, S-005, S-006, S-008. - Flag creation with confidence + evidence storage. - Review queue API. - Acceptance: flags for synthetic cheats; no false positives on clean sessions. Stage 3: Dashboard (2-3 weeks) - Auth (email+password+TOTP), JWT, RBAC. - Overview, players, flags, bans, audit log pages. - Ban issue/revoke with Discord webhook. - Acceptance: owner can log in, view flags, issue ban, ban appears in PlayFab. Stage 4: Currency/cosmetic protection (1-2 weeks) - Move currency grants to worker/CloudScript. - Backend inventory verification for cosmetics. - Acceptance: client cannot grant itself currency; cosmetic spoof flagged. Stage 5: Testing & hardening (1-2 weeks) - Pen test, load test (k6), false-positive regression, backup restore. - Acceptance: all tests pass, no critical findings. Stage 6: Controlled rollout (1 week) - Staging with PCDEBUG (two-editor test). - Limited QA rollout, monitoring, gradual expansion. Total: ~9-14 weeks solo, part-time. Depends on Stage 0 findings. ================================================================================ 15. Security test register ================================================================================ All tests are planned, not executed. No fabricated results. Authentication tests: - Invalid identity proof -> login denied. - Arbitrary Custom ID -> login denied (if Meta User Verification implemented). - Expired/revoked session -> connection denied. - Replay of one-time proof -> connection denied. - Account linking without proof -> connection denied. - Invalid Photon credentials -> connection denied. - Banned user -> connection denied (via custom auth). - Backend outage -> connection denied (fail closed). - Legacy client -> connection denied (version check). Authorization tests: - Self-promotion -> server rejects (if UserData is client-writable, flag as vulnerability). - Unauthorized access -> 403. - Protected endpoints -> 401/403. - Invalid token -> 401. - Secret exposure -> none in client (verified). Economy tests: - Arbitrary currency grant -> server rejects (after fix). - Insufficient balance purchase -> server rejects. - Duplicate purchase -> idempotency prevents. - Replayed redemption -> server rejects (worker validates code). - Invalid receipt -> server rejects (if receipt validation implemented). - Unowned cosmetic -> flag (after backend inventory check). Multiplayer tests: - Invalid RPC params -> flag/reject. - RPC flood -> rate limit + flag. - Invalid tag/infection -> flag. - Client-controlled scene changes -> flag. - Unowned cosmetic props -> flag. - Master client changes -> log. - Movement anomalies -> flag (heuristic). - Telemetry limits -> flag. Reliability tests: - Worker outage -> fail closed for auth, fail open for gameplay. - DB outage -> audit log delayed, core auth works. - Quota exhaustion -> 429, fail closed. - Auth service failure -> fail closed. - Session revocation -> reject revoked sessions. - Backup restore -> verify data integrity. - Compromised admin session -> revoke + audit log. - Monitoring/alerts -> verify alert delivery. ================================================================================ 15b. Dashboard owner-only security ================================================================================ Closed registration: No public signup. Dashboard is private by default. Initial owner enrollment: Secure out-of-band process (e.g., CLI command, invite link with single-use token, or manual DB insert by developer). No self-service registration. No ability to create another owner account from within the dashboard. Backend authorization: Every sensitive API endpoint verifies identity and owner permissions server-side. Deny-by-default. Direct API calls bypassing the frontend are blocked (backend-enforced, not frontend-hidden). MFA enforcement: TOTP required for all owner actions. Login rate limit: 5 attempts per 15 minutes per IP. Account lockout after 10 failed attempts. Session security: Short-lived access tokens (15 min) + refresh tokens (7 days, rotating, revoked on logout). Secure cookie handling (SameSite=Strict, HttpOnly, Secure). Session revocation on password change or MFA reset. Secure recovery: Password reset via email (time-limited link). MFA reset requires out-of-band verification (e.g., email + security question or admin approval). No self-service owner creation or promotion. CSRF protection: SameSite cookies + CSRF tokens for state-changing requests. Not applicable if using Bearer token auth (no cookies). Audit logging: All login attempts (success/failure), player lookups, moderation actions, settings changes, rule changes, ban/unban actions logged with actor, timestamp, IP, and reason. Secret storage: All secrets in worker env vars (Cloudflare dashboard, encrypted at rest). No privileged credentials in frontend JavaScript. No API keys in client. Emergency access revocation: Owner can revoke all sessions, rotate JWT secret, disable dashboard access. Process documented. Additional staff roles: RBAC (Owner/Admin/Moderator/Viewer). Least privilege. No role can escalate to Owner. Owner role cannot be assigned via dashboard. Dashboard security test plan (all UNEXECUTED): 1. Unauthenticated API requests -> expect 401. 2. Registration attempts -> expect 404 (no registration endpoint). 3. Non-owner account -> expect 403 on all sensitive endpoints. 4. Direct API calls bypassing frontend -> expect 401/403 (backend-enforced). 5. Role escalation attempt -> expect 403 (server-side role check). 6. Owner creation attempt -> expect 403 (no endpoint exists). 7. Expired session -> expect 401. 8. Revoked session -> expect 401. 9. Stolen session token -> expect 401 (if token rotation/revocation implemented). 10. MFA bypass -> expect 403 (MFA required for all owner actions). 11. Login brute force -> expect 429 (rate limit). 12. CSRF (if cookie-based) -> expect 403 (CSRF token mismatch). 13. Account recovery abuse -> expect rate limit + verification. 14. Emergency session revocation -> verify all sessions invalidated. 15. Secret exposure in frontend -> verify no secrets in JS bundle. All tests are PLANNED, not executed. No fabricated results. ================================================================================ 16. Corrections made ================================================================================ 1. Photon authentication: Worker cannot validate PlayFab session ticket if it only receives Photon auth token. Client does not need to send session ticket; worker validates Photon token via PlayFab API using its own credentials. CORRECTED: earlier claim that client MUST send session ticket was wrong. 2. Heartbeat cost: 10s heartbeat = 8,640 req/player/day. At 100 CCU = 864,000 req/day (exceeds free tier). Revised to 30s request + 5-min D1 write. Or use KV for session state. 3. Meta Attestation: Token valid 24h by default (configurable). Server must validate exp (within 24h), nonce (one-time), timestamp (recent), app_integrity_state (StoreRecognized), package_cert_sha256_digest, device_integrity (Advanced/Basic). Rate limits: 100/hr, 200/day per device. security_update_pending_days only for Advanced/Basic. CORRECTED with official docs (previously docs were 404, now accessible). 4. Meta User Verification: getUserProof returns proof of account control. Server validates nonce (server-generated, one-time). DIFFERENT from App Attestation challenge_nonce. User Verification proves identity; App Attestation proves device/app integrity. CORRECTED (previously conflated). "Hardware-bound" wording corrected. 5. Currency grants: Reclassified as CONDITIONAL. PlayFab AddUserVirtualCurrency accepts client-specified amount (validates session, not amount). Whether clients can actually call it depends on PlayFab title settings. Keep server-authoritative as recommended design regardless. 6. Photon pricing: VERIFIED from official page. Free tier 20 CCU (dev only). 100 CCU = $95 one-time (12-month term). 500 CCU = $95/mo. 1000 CCU = $185/mo. 2000 CCU = $370/mo. Premium Cloud = $0.29/CCU, min $580/mo. Voice separate. PUN 2 is in maintenance/LTS mode. 7. Untested guarantees: Changed every untested security guarantee to conditional. Distinguish current (verified), proposed (designed), tested (executed). No test has been executed. All tests are planned. 8. Game-server hosting: Confirmed that "game-server hosting is already handled" refers to Photon Cloud (relay), NOT an authoritative dedicated server. Photon Cloud does not run game logic. No authoritative gameplay currently exists. 9. Dashboard owner-only: Added explicit closed-registration, owner-enrollment, backend authorization, MFA, rate limiting, CSRF, audit logging, secret storage, emergency revocation, and 15 unexecuted tests. (NEW) What was NOT corrected (still valid): - Tomahawk public site research (features, pricing, roles, integration methods). - Local file research (getting started, API reference, portal docs, unity implementation, error codes). - Ghidra binary analysis (native lib is thin wrapper + OpenSSL). - Quest modification threat catalog (comprehensive, verified identities). - Trust boundary analysis (client untrusted, backend trusted). - Detection engine design (risk scoring, graduated response). - Dashboard design (pages, auth, security). - Cost estimates (revised with official pricing). ================================================================================ 17. Unresolved questions ================================================================================ 1. PlayFab UserData "Moderator" key: client-writable? (CRITICAL) - requires dashboard access. 2. CloudScript/Azure Functions deployed? (none in repo) - requires dashboard access. 3. PlayFab PurchaseItem validates price server-side? - requires dashboard/catalog config. 4. PlayFab bans enforced server-side? - requires dashboard access. 5. Meta attestation available to ScreechVR? - docs accessible, but eligibility/permissions unverified. 6. Photon custom auth configured? - requires dashboard access. 7. "Allow anonymous clients" disabled? - requires dashboard access. 8. Dev/prod app IDs separate? - requires dashboard access. 9. SpokesSigmaIAP receipt validation - requires reading script + catalog. 10. GDH leaderboard anti-cheat - requires inspecting GDH package. 11. ATM_TAB currency flow - requires reading ATM_TAB.cs + Atm_Manager.cs. 12. D1 write throughput sufficient - requires load test (k6). 13. Free tier limits sufficient - requires monitoring post-launch. 14. AppEntitlementCheck intended behavior - requires verification. 15. Meta User Verification SDK compatibility with Unity 2021.3.32f1 - requires testing. 16. Data retention policy preferences - requires user decision. 17. Budget ceiling and solo-dev time availability - requires user decision. 18. Evidence storage needs (telemetry vs screenshots/video) - requires user decision. 19. Existing server infrastructure: can it run trusted game logic? (Photon Cloud = relay only. No.) 20. Photon PUN 2 maintenance status: in LTS/maintenance mode. Photon recommends Fusion for new projects. ================================================================================ 18. Research activity log ================================================================================ Inspected during this pass: - research/ (27 reports, README, FINAL_RESEARCH_SUMMARY) - research/FINAL_SECURITY_ARCHITECTURE/ (26 deliverables) - docs/screechvr-technical-map-2026-10-28.md - docs/voideration-screechvr-architecture.md - docs/voideration-anticheat-research.md - docs/voideration-anticheat-review.md - research/QUEST_MODIFICATION_THREAT_CATALOG.md - SHARED-MEMORY.md, AGENTS.md - Source files: Oculus_Login.cs, ScreechApi.cs, BuyCosmetic.cs, PhotonVRManager.cs (partial), Player.cs (partial), TagPlayer.cs, TagManager.cs, KickIfBanned.cs, AppEntitlementCheck.cs, UsernameValidator.cs, PlayerSpawner.cs, BestJumpscare.cs, GetCosmetics.cs, SecondaryCosmetics.cs, LevelSelect.cs, MapLoader.cs, Gamemode_System.cs, GamemodeManager.cs, Hand_Physic.cs Official documentation fetched: - Meta Quest Attestation API (https://developers.meta.com/vr/documentation/native/ps-attestation-api/) - FULLY ACCESSIBLE (2026-10-29) - Photon pricing (https://www.photonengine.com/realtime/pricing) - FULLY ACCESSIBLE (2026-10-29) - Photon custom authentication (https://doc.photonengine.com/pun/current/connection-and-authentication/authentication/overview-auth) - ACCESSIBLE - OWASP API Security Top 10 2023 - ACCESSIBLE - OWASP Cryptographic Storage Cheat Sheet - ACCESSIBLE - Unity IL2CPP docs - ACCESSIBLE - Unity AssetBundles docs - ACCESSIBLE Documents created during this pass: - research/FINAL_SECURITY_CORRECTION_BUNDLE.txt (this file) - research/FINAL_SECURITY_CORRECTION/CORRECTION_INDEX.md (correction index) Documents updated during this pass: - research/FINAL_SECURITY_CORRECTION/CORRECTION_INDEX.md (new) What was NOT done: - No implementation code written. - No project files modified. - No services deployed. - No dashboard access. - No tests executed. - No credentials reproduced. - No production data changed. ================================================================================ 19. Source register ================================================================================ Official documentation: - Meta Quest Attestation API: https://developers.meta.com/vr/documentation/native/ps-attestation-api/ (ACCESSIBLE 2026-10-29) - Meta User Verification: https://developers.meta.com/vr/documentation/spatial-sdk/ps-ownership/ (GATED - 404) - PlayFab login best practices: https://learn.microsoft.com/gaming/playfab/identity/player-identity/login/login-basics-best-practices - Photon PUN custom authentication: https://doc.photonengine.com/pun/current/connection-and-authentication/authentication/custom-authentication - Photon PUN host migration: https://doc.photonengine.com/pun/current/gameplay/hostmigration - Photon pricing: https://www.photonengine.com/realtime/pricing (ACCESSIBLE 2026-10-29) - Cloudflare Workers pricing: https://developers.cloudflare.com/workers/platform/pricing/ - Cloudflare D1 limits: https://developers.cloudflare.com/d1/platform/limits/ - Cloudflare D1 pricing: https://developers.cloudflare.com/d1/platform/pricing/ - Cloudflare Durable Objects + WebSockets: https://developers.cloudflare.com/durable-objects/best-practices/websockets/ - Nakama authoritative multiplayer: https://heroiclabs.com/docs/nakama/concepts/multiplayer/authoritative/ - Unity upgrade guide: https://docs.unity.com/en-us/engine/7000.0/manual/upgrade-guides/upgrade-guide-unity63 - OWASP MASVS: https://mas.owasp.org/MASVS/ - OWASP API Security Top 10 2023: https://owasp.org/API-Security/editions/2023/en/0x11-t10/ - OWASP Cryptographic Storage Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html Local research files: - C:\Users\Void\Downloads\tomahawk stuff\ (all files, read-only) - libTomahawkCore.so (5.3MB, SHA-256: 150710A0ED22048DDD3B18C49D7837EA60803B67DE768A6160DFF6A96ADD2B85) Project files: - E:\! Project Screech\! Screech VR\Screech VR\ (Unity project, read-only during research) Confidence levels: - Confirmed: verified against source code or official docs. - Strong evidence: multiple sources agree, code partially verified. - Plausible: reasonable inference, not verified. - Historical: was true in the past, current status unknown. - Unverified: cannot confirm, needs additional access/testing. ================================================================================ 20. Final decision ================================================================================ Best free-first starting architecture: Cloudflare Workers + D1 + KV + R2 (backend) + Cloudflare Pages (dashboard) + PlayFab (auth/inventory/bans) + Photon PUN 2 + Voice (networking). No dedicated game server for v1. No new providers. Extend existing infrastructure. Game-server hosting is "handled" but this is Photon Cloud (relay), not authoritative. No additional cost. Best authentication model: Meta User Verification (getUserProof, server-side) + PlayFab (persistent account) + Photon custom auth (room admission) + Voideration JWT (dashboard/API). Each token verified independently by its issuer. PlayFab session ticket is NOT needed as custom auth param; worker validates Photon token via PlayFab API using its own credentials. Best long-term anti-cheat architecture: Server-authoritative where possible (currency, bans, cosmetics, version) + heuristic detection for movement + manual review + private dashboard. Accept that movement exploits can only be detected, not prevented, without dedicated server. Migrate to Photon Fusion or dedicated server (v2) only if cheating becomes serious. Game-server hosting is already handled but is relay-only; authoritative gameplay requires migration. Five highest-priority vulnerabilities: 1. Client-trusted currency (AddCurrency local-first, PlayFab validates session not amount). CONDITIONAL on PlayFab title settings. 2. Client-trusted moderator status (PlayFab UserData "Moderator" key, likely client-writable). CONDITIONAL on PlayFab permissions. 3. Client-side ban enforcement (KickIfBanned polls every 5s, ignorable). FIX: Photon custom auth ban check. 4. No movement validation (speed/teleport exploits, heuristic detection only). DETECT ONLY. 5. Master client abuse (scene sync, room state manipulation). MINIMIZE AUTHORITY. Key costs: - Initial: $1-35/mo (Cloudflare free tier + domain). - 100 CCU: $5-16/mo (Cloudflare) + $95/12mo (Photon, one-time). - 500 CCU: $16-33/mo (Cloudflare) + $95/mo (Photon) = $111-128/mo. - 1000 CCU: $16-40/mo (Cloudflare) + $185/mo (Photon) = $201-225/mo. - Trade-off: engineering time (9-14 weeks MVP, 5-10h/week ops). Explicit statement: Research is complete. No implementation performed. No project files modified. No services deployed. No production data changed. Awaiting explicit approval before any code is written. ================================================================================ END OF REPORT ================================================================================