Pastebin

Untitled

text 8 views Created: October 30, 2026 at 11:29:10 EDT
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
SCREECHVR AUTH REVIEW V15: PLAYFAB IDENTITY + PHOTON AUTH
Date: 2026-10-30
Scope: Read-only source and documentation review. No code, Unity files, revisions,
dashboards, or production services changed. V08 remains an unverified draft.

SUMMARY

Current code turns the Meta ID returned to the client into a PlayFab Custom ID,
without proving that ID to PlayFab. Photon normally uses a PlayFab-issued Photon
token, but PhotonVRManager falls back to a connection with no AuthValues after
waiting 20 seconds. These are source-confirmed trust weaknesses. Whether the
Photon fallback is admitted by production Photon settings is unverified.

1. PLAYFAB IDENTITY

Source and flow
- `! Screech VR/Screech VR/Assets/Scripts/Oculus_Login.cs`
- `Start()` initializes Meta Platform and requests `Users.GetLoggedInUser()`.
  `OnUserLogin()` assigns `msg.Data.ID.ToString()` to `OculusID` and invokes
  `Login()` (source lines approximately 100-181; local source checked).
- `Login()` calls PlayFab `LoginWithCustomID` with `CustomId = OculusID` and
  `CreateAccount = true`. The client sends no Meta proof to PlayFab/backend.
- `OnLoginSuccess()` stores `PlayFabId` and `SessionTicket`, then requests a
  Photon token. Session ticket is used by authenticated PlayFab client calls;
  source inspection found no Meta proof validation or server-side identity
  binding in this flow. Protect tickets as credentials; do not log them.
- `AppEntitlementCheck.cs` is a separate client entitlement check and does not
  independently authenticate the Meta ID to PlayFab. Its failure behavior is
  not a substitute for account identity verification.

Confirmed vulnerability vs uncertainty
- Confirmed: `LoginWithCustomID` accepts the client-provided Meta ID without a
  server-verified proof in this path. PlayFab documents CustomId as a title-
  generated unique ID and warns that predictable/reused values risk account
  impersonation. A modified client can submit another known ID. This is an
  authentication design flaw; practical exploitability and any additional live
  restrictions are not established here.
- Not verified: PlayFab title API policies, deployed server-side login controls,
  account linking/recovery policy, or production enforcement settings.

Meta `getUserProof`
- Official Meta User Verification documentation describes `Users.GetUserProof()`
  as a client-provided, one-use nonce; a trusted backend submits nonce plus user
  ID to Meta `https://graph.oculus.com/user_nonce_validate` using app credentials.
  A successful verification proves the Meta account identity for that request.
- It is not safe to call the client API and trust its result. Backend must call
  Meta, ensure the nonce is one-use/fresh, bind the verified identity to the
  account, and keep Meta app secret exclusively server-side. Meta says User
  Verification does not replace Entitlement Check. User ID Data Use Checkup
  permission is required; app eligibility/DUC and SDK compatibility must be
  confirmed for this project.
- Recommended flow: Unity obtains Meta user ID + proof nonce; sends both via TLS
  to backend; backend verifies with Meta S2S using secret, obtains/uses a stable
  verified account key (Meta documents org-scoped ID retrieval after verification),
  and maps it to a PlayFab account. Backend then issues/authorizes a short-lived
  game credential. Avoid retaining an unverified client ID as account authority.
  Migration must preserve existing PlayFab IDs, inventory, purchases, and recovery.
- If direct PlayFab login is retained, a backend-mediated identity exchange must
  securely bind verified Meta identity to the intended PlayFab account; do not
  put PlayFab title secret or Meta app secret in Unity. Do not assume a custom
  ID derived in client code becomes secret or unforgeable.

2. PHOTON AUTHENTICATION

Source and flow
- `! Screech VR/Screech VR/Assets/Scripts/Oculus_Login.cs`: `OnLoginSuccess()`
  calls `PlayFabClientAPI.GetPhotonAuthenticationToken` with the configured
  Photon Realtime App ID; success stores `PhotonCustomAuthToken` and marks Photon
  readiness. The PlayFab session ticket authorizes that request; it is not itself
  the Photon token.
- `! Screech VR/Screech VR/Assets/Scripts/PhotonVRManager.cs`: `Start()` starts
  `WaitForAuthThenConnect()` when `ConnectOnAwake` is set. The coroutine waits
  up to 20 seconds for `Oculus_Login.IsPhotonReady`; on success it calls
  `ConnectAuthenticated(PlayFab_Id, PhotonCustomAuthToken)`. That method sets
  `AuthenticationValues` to Custom and adds `username` (PlayFab ID) and `token`
  (PlayFab Photon token), then connects.
- On timeout/not-ready it calls `Connect()`, which clears
  `PhotonNetwork.AuthValues` and connects without those credentials. This is a
  confirmed unauthenticated fallback in source. Photon documents anonymous
  clients as assigned a random ID when no authentication values are provided.
- Token request failure does not make `IsPhotonReady` true; thus the 20-second
  wait reaches the same unauthenticated fallback. No credential-refresh/retry
  recovery is implemented in this manager's `OnDisconnected()` path; it updates
  state only. `OnConnectedToMaster()` may automatically join a room based on
  `JoinRoomOnConnect`.
- `ConnectRandom()` sets auth values but only calls `JoinRandomRoom` in the
  inspected method; it is not evidence of a fresh authenticated connect. Audit
  its callers and connection lifecycle before changing it.

Confirmed vs dashboard-dependent
- Confirmed: fallback clears auth and attempts connection without PlayFab
  custom credentials; timeout and token-fetch failure can reach that code path.
- Dashboard-dependent: Photon application’s custom auth provider URL, anonymous
  client option, fail-closed behavior when the provider is unavailable, app-ID
  association, and whether the live app accepts the fallback. No dashboard
  settings were accessed or verified.
- Reconnect: no explicit application-level credential reacquisition is present
  in this manager. Photon may handle its own server-switch/reconnect token flow
  after an authenticated connection, but that does not make the initial
  unauthenticated fallback safe. Verify the exact PUN version and reconnect
  behavior in staging; do not assume reconnect bypasses or enforces auth.

Required Photon dashboard configuration (do not change in this review)
- Configure the Photon Realtime application’s Custom Server authentication
  provider URL as PlayFab documents:
  `https://<PlayFabTitleId>.playfabapi.com/photon/authenticate`
- Disable “Allow anonymous clients to connect, independently of configured
  providers” for the relevant app. Photon’s PlayFab integration marks this
  recommended; verify its exact setting in the dashboard.
- Confirm the PlayFab Photon add-on is associated with the same Realtime App ID
  used by `GetPhotonAuthenticationToken`; configure/test Voice app authentication
  separately if its app ID differs.
- Ensure Photon rejects failed/unavailable custom authentication rather than
  accepting fallback; test provider outage behavior and app IDs in a non-prod app.

3. RECOMMENDED IMPLEMENTATION ARCHITECTURE

Unity changes (future work only)
- Gate Photon connect on successful PlayFab login AND successful Photon token
  retrieval. On timeout/error, show retry/error state and do not call anonymous
  `Connect()`. Keep offline/dev paths explicit and unavailable in production.
- Centralize auth state transitions: authenticated, retryable network failure,
  permanent credential/configuration failure, signed-out. Bound retries with
  backoff; do not start multiple concurrent login/token requests.
- Reconnect by obtaining a fresh PlayFab Photon token when needed, setting
  Custom AuthValues, then connecting. Confirm PUN-managed server switches remain
  compatible. Never silently downgrade on reconnect.
- For Meta identity, add `GetUserProof` only with backend S2S validation and an
  account migration/linking design. Keep all server credentials backend-only.

Backend changes (future work only)
- Add authenticated Meta-proof verification endpoint: validate Meta nonce and
  user ID server-to-server; enforce freshness/one-use, rate limit, strict input
  validation, TLS, secret storage, and audit without logging proof/credentials.
- Bind verified stable Meta identity to PlayFab account. Define account recovery,
  duplicate-link behavior, migration of existing accounts, and rollback first.
- For Photon custom auth, use PlayFab’s official Photon integration endpoint
  unless a concrete requirement demands a custom provider. Do not confuse Worker
  `/photonwh/*` webhooks with Photon player authentication: they handle webhook/
  CCU events, not player credential validation. No general game-auth endpoint
  or Meta proof validator was found in `discord-bot/worker.js`.
- Backend must never trust a PlayFab ID sent alone by client; validate the
  PlayFab session ticket server-side when custom backend authorization requires
  it. Keep Meta and PlayFab server secrets out of client builds.

4. FAILURE, RECONNECT, AND COMPATIBILITY POLICY

- Meta proof service unavailable: do not create a new unverified account or
  silently bind a different identity. Offer retry; existing account access may
  follow a documented, verified recovery policy.
- PlayFab login/token request timeout: bounded retry/backoff; no Photon connect.
- Photon auth rejection/provider outage: surface retryable vs configuration
  failure; do not fall back to anonymous. Preserve room matchmaking after
  authentication succeeds.
- Expired Photon credential/reconnect: obtain fresh token via valid PlayFab
  session, then reconnect authenticated. If PlayFab session expired, reauthenticate
  through the identity flow. Avoid duplicate Photon managers/connections.
- Roll out with a staging Photon app and test accounts first. Existing users must
  retain PlayFab ID, data, currency, owned cosmetics, and IAP entitlements.

5. SMALL REGRESSION TEST PLAN

1. Existing legitimate Meta account logs in; same PlayFab ID and inventory remain.
2. Alter client-supplied Meta ID while proof belongs to another user: backend
   rejects mismatch; no account is created/linked to the victim.
3. Reuse an already-consumed Meta proof nonce: rejected; no session issued.
4. Meta unavailable/DUC or permission failure: clear recoverable error; no
   unverified identity fallback.
5. PlayFab login succeeds, Photon token succeeds: custom auth connects and room
   join/voice/matchmaking behavior is unchanged.
6. Delay/fail Photon-token request beyond 20 seconds: no unauthenticated connect;
   retry works after service recovery.
7. Reject token or disable custom-auth provider in staging: Photon refuses
   connection; no anonymous session is admitted.
8. Disconnect/reconnect and server switch: fresh/managed auth succeeds; expired
   credentials do not trigger an anonymous downgrade or duplicate connection.
9. Test Realtime and Voice app IDs/config independently; verify correct identity
   and normal room/voice behavior.

6. REMAINING UNKNOWNS

- Live PlayFab title/API policies, deployed CloudScript/Functions, and any
  additional identity binding not present in inspected source.
- Photon dashboard configuration, anonymous-client setting, provider outage
  policy, Realtime/Voice app IDs, and production connection path.
- Meta DUC/User ID permission, app eligibility, Unity Platform SDK version/API
  availability in Unity 2021.3.32f1, and review requirements.
- Whether Oculus ID vs org-scoped ID is the correct durable account key for this
  title; confirm with Meta documentation and migration constraints before design.
- Exact PUN package version and reconnect/server-switch behavior in this project.
- Source review was targeted, not a complete audit of all login callers or every
  scene’s PhotonVRManager configuration.

OFFICIAL DOCUMENTATION CONSULTED

- Meta Unity User Verification: https://developers.meta.com/vr/documentation/unity/ps-ownership/
- Meta S2S API basics/secrets: https://developers.meta.com/vr/documentation/unity/ps-s2s-basics/
- PlayFab LoginWithCustomID: https://learn.microsoft.com/en-us/rest/api/playfab/client/authentication/login-with-custom-id
- PlayFab login best practices: https://learn.microsoft.com/en-us/gaming/playfab/identity/player-identity/login/login-basics-best-practices
- PlayFab GetPhotonAuthenticationToken:
  https://learn.microsoft.com/en-us/rest/api/playfab/client/authentication/get-photon-authentication-token
- Photon PUN PlayFab integration/dashboard setup:
  https://doc.photonengine.com/pun/current/reference/playfab
- Photon PUN auth overview:
  https://doc.photonengine.com/pun/current/connection-and-authentication/authentication/overview-auth

No code or production changes. This report is a focused supplement, not a
replacement for V14.

END OF REPORT

Embed this paste

Install this app

  1. Tap the Share button
  2. Scroll down and tap "Add to Home Screen"
  3. Tap "Add" in the top right

Please confirm