fix(multiplayer): validate match admission context

This commit is contained in:
Josh Creek
2026-09-01 22:51:15 +01:00
parent 3bd2387dc3
commit 807aaa4478
3 changed files with 7 additions and 1 deletions
+1 -1
View File
@@ -115,7 +115,7 @@ func configure_join_authorisations(tokens: Array, context: Dictionary, signing_k
if not token is String or String(token).is_empty():
return false
allowed[String(token)] = true
if allowed.is_empty() or String(context.get("match_id", "")).is_empty() or String(context.get("server_id", "")).is_empty() or int(context.get("protocol_version", 0)) < 1:
if allowed.is_empty() or not context.has("match_id") or not context["match_id"] is String or String(context["match_id"]).is_empty() or not context.has("server_id") or not context["server_id"] is String or String(context["server_id"]).is_empty() or not context.has("protocol_version") or not _valid_integer_claim(context["protocol_version"]) or int(context["protocol_version"]) < 1:
return false
_allowed_join_authorisations = allowed
_join_authorisation_context = context.duplicate(true)
+4
View File
@@ -96,6 +96,10 @@ func test_allocated_join_authorisation_is_allowlisted_and_bound_to_server() -> v
match_net._remove_player(43)
match_net._join_history[token]["lost_at"] = Time.get_unix_time_from_system() - MatchNet.RECONNECT_GRACE_SECONDS - 1.0
assert_eq(match_net._reserve_join_authorisation(token, 44), -1, "reclaim after the grace window is fenced")
var malformed_context := {"match_id": 123, "server_id": "server-1", "protocol": "1", "protocol_version": 1}
assert_true(not match_net.configure_join_authorisations([token], malformed_context), "numeric context identity is rejected")
malformed_context = {"match_id": "match-1", "server_id": "server-1", "protocol": "1", "protocol_version": 1.5}
assert_true(not match_net.configure_join_authorisations([token], malformed_context), "fractional context protocol is rejected")
func test_allocated_join_authorisation_rejects_inconsistent_team_and_slot() -> void:
+2
View File
@@ -1605,6 +1605,8 @@ Control-plane REST responses now fail closed on malformed ticket, proposal, or s
Session establishment now also requires a present, syntactically valid, future `expires_at`, preventing malformed authentication responses from creating an unbounded client session.
MatchNet admission configuration now requires exact string opaque match/server IDs and a finite integral protocol version, preventing malformed server context from being coerced into a valid roster binding.
Signed MatchNet claims now also require exact JSON string/integer types for every identity, protocol, expiry, slot, team, and generation field; string-number coercion is rejected before canonical signature verification.
Presentation progress: a shared `Game/themes/cosmic_clash_theme.tres` now gives the menu, lobby, matchmaking, and settings surfaces consistent button, input, option, and label styling. The custom-font portion of `TODO.md` remains open until a distributable font asset is selected.