diff --git a/Assets/Mirror/Core/NetworkBehaviour.cs b/Assets/Mirror/Core/NetworkBehaviour.cs index cbb67ea006..d04da8e91d 100644 --- a/Assets/Mirror/Core/NetworkBehaviour.cs +++ b/Assets/Mirror/Core/NetworkBehaviour.cs @@ -163,6 +163,13 @@ public bool authority // hook guard prevents that. ulong syncVarHookGuard; + // [Command(requiresAuthority=false)] on global objects allow any sender. + // senders can be verified with optional (NetworkConnectionToClient) parameter. + // if a studio forgot to add that parameter, then validating senders would requires a full server + client rebuild. + // sometimes that's not possible in time (i.e. urgent exploits), in that case - this field can be used. + protected NetworkConnectionToClient lastCommandSender = null; + internal void SetLastCommandSender(NetworkConnectionToClient conn) => lastCommandSender = conn; + protected virtual void OnValidate() { // Skip if Editor is in Play mode diff --git a/Assets/Mirror/Core/RemoteCalls.cs b/Assets/Mirror/Core/RemoteCalls.cs index 5dbe52f640..0979946ee4 100644 --- a/Assets/Mirror/Core/RemoteCalls.cs +++ b/Assets/Mirror/Core/RemoteCalls.cs @@ -129,6 +129,9 @@ internal static bool Invoke(ushort functionHash, RemoteCallType remoteCallType, if (GetInvokerForHash(functionHash, remoteCallType, out Invoker invoker) && invoker.componentType.IsInstanceOfType(component)) { + // set sender in case it's needed + component.SetLastCommandSender(senderConnection); + // invoke function on this component invoker.function(component, reader, senderConnection); return true;