Home / Forums / Photon PUN Security Flaw: Why Room.SetCustomProperties is Client-Tamperable & How to Fix It

UnreliableCode Community

Developer Research, Reverse Engineering & Coding Community

Tutorial

Photon PUN Security Flaw: Why Room.SetCustomProperties is Client-Tamperable & How to Fix It

SecurityAudit
AppSec & Code Auditor
MEMBER
Rep: 135
Join Date: Jan 2025
Posts: 28
Thanks: 29
1y ago · Nov 12, 2024 2:30 PM
#1
The Architecture Problem in Photon PUN (Photon Unity Networking)
In many indie Unity multiplayer games using Photon PUN 2 or Photon Realtime, developers mistakenly assume that only the Room Host (MasterClient) can modify Room properties.

By default in Photon PUN, **any connected client** in a room can invoke:
CSHARP
ExitGames.Client.Photon.Hashtable props = new ExitGames.Client.Photon.Hashtable();
props["RoomName"] = "Hacked Room Name";
props["GameMode"] = "Deathmatch";
props["MaxScore"] = 999999;

PhotonNetwork.CurrentRoom.SetCustomProperties(props);


Because Photon Cloud acts primarily as a relay server without custom server-side game logic by default, the relay server broadcasts the new custom properties to **all clients in the room** without verifying if the sender is the MasterClient!

---

Common Vulnerable Implementations:
1. Room Name / Title in CustomProperties: Storing the room display title in
CODE
customProperties["name"]
allows any random player joining the lobby to rename the room or inject spam.
2. Match State / Map Selection: Overwriting
CODE
customProperties["State"] = "Ended"
or forcing map changes mid-game.
3. Score / Team Points: Client-authoritative score tracking where any client sets team scores directly.

---

How to Secure Your Photon Game (Defensive Best Practices):

1. Use Check-And-Set (CAS / expectedProperties):
Always pass
CODE
expectedProperties
so the server only applies the change if the existing value matches an expected state token:
CSHARP
// Only updates if the previous version matches
PhotonNetwork.CurrentRoom.SetCustomProperties(props, expectedProperties);


2. Photon Server Plugins / Enterprise Webhooks (PathProperties):
On self-hosted Photon Server or Photon Enterprise Cloud, implement the
CODE
BeforeSetProperties
plugin hook on the server side:
CSHARP
public override void BeforeSetProperties(BeforeSetPropertiesRequest request) {
    // Reject property changes if the actor is not the MasterClient!
    if (request.ActorNumber != 1) {
        request.Cancel();
    }
}


3. Client-Side Verification & Ignoring Non-Master Broadcasts:
In
CODE
OnRoomPropertiesUpdate
, verify if the update originated from a trusted state, or validate authoritative game rules strictly through MasterClient RPCs before accepting state transitions.
SecurityAudit | Secure C++ Architecture & Boundary Auditing
The following users thanked SecurityAudit for this post:
PacketSniffer
Network Protocols & Sockets
MEMBER
Rep: 195
Join Date: Sep 2024
Posts: 22
Thanks: 49
1y ago · Nov 12, 2024 4:15 PM
#2
Spot on writeup @SecurityAudit! We saw this exact issue in several popular Unity co-op horror and party games where joiners could modify the room's custom properties and change the active gamemode or difficulty before the host started the match.

Adding server-side webhook validation via Photon WebHooks (
CODE
PathProperties
callback to your web backend) is an easy way to reject unauthorized client property updates without maintaining custom C++ dedicated servers.
PacketSniffer | Network Protocols & Winsock SPI
SharpShooter_x
Unity C# Modder
MEMBER
Rep: 234
Join Date: May 2024
Posts: 8
Thanks: 29
1y ago · Nov 12, 2024 6:40 PM
#3
Another common pitfall is storing player inventory items or currency inside
CODE
PhotonNetwork.LocalPlayer.SetCustomProperties()
. Since player custom properties are completely client-controlled, clients can spoof their owned weapon IDs.

Critical persistent data should always be validated against a secure REST backend (PlayFab / Supabase / custom database API) rather than trusted in Photon room properties!
SharpShooter_x · Unity C# Modder
Deep diving into Unity script lifecycles, IL2CPP internals, ...
DevDan
.NET Core & Cloud
MEMBER
Rep: 324
Join Date: Feb 2021
Posts: 16
Thanks: 65
1y ago · Nov 13, 2024 9:20 AM
#4
Originally Posted by @SecurityAudit
Because Photon Cloud acts primarily as a relay server without custom server-side game logic by default

This is why Photon Fusion and Quantum moved towards server-authoritative topologies. For PUN2 developers, implementing Webhooks or using MasterClient RPC validation is an absolute necessity.
DevDan · .NET Core & Cloud
Writing clean C# code and microservices since .NET Core 2.1....