THE SHORT ANSWER
Roblox Remote Security: Let the Client Ask, Let the Server Decide A determined exploiter can fire or invoke RemoteEvents and RemoteFunctions at arbitrary frequencies with arbitrary arguments, except for the first Player argument supplied to a server callback. Treat every client request as untrusted. Understand the boundary RemoteEvents provide asynchronous.
- A determined exploiter can fire or invoke RemoteEvents and RemoteFunctions at arbitrary frequencies with arbitrary arguments, except for the first Player argument supplied to a server callback.
- RemoteEvents provide asynchronous, one-way communication without yielding, while RemoteFunctions provide synchronous, two-way communication and yield until a response is received.
- For client-to-server communication, OnServerEvent and OnServerInvoke receive the invoking player as their first server-side argument.
- Every piece of client-supplied data must be validated by the server before it is used.
- Roblox recommends validating input types, structures, sizes, identifiers, values, permissions, and context, and checking an Instance's type, class, and expected DataModel location.
- NaN and positive or negative infinity are valid numeric types; in Luau, value ~= value detects NaN and math.abs(value) == math.huge detects either infinity.
- The server should be authoritative for game rules, player progression, and critical decisions, including verifying authoritative prices, balances, and relevant context before completing a purchase.
- Before applying combat damage, the server can validate reported positions, obstructions, firing rate, ammunition, weapon state, and target eligibility.
Roblox Remote Security: Let the Client Ask, Let the Server Decide
A determined exploiter can fire or invoke RemoteEvents and RemoteFunctions at arbitrary frequencies with arbitrary arguments, except for the first Player argument supplied to a server callback. Treat every client request as untrusted.
Understand the boundary
RemoteEvents provide asynchronous, one-way communication without yielding for a response. RemoteFunctions provide synchronous, two-way communication and yield until the recipient responds.
For client-to-server communication, OnServerEvent and OnServerInvoke receive the invoking player as their first server-side argument. Use that identity instead of accepting a player identity from the client.
Validate before use
Roblox's security guidance says every piece of client-supplied data must be validated by the server before use. Apply checks appropriate to the operation:
- Verify types and table structure.
- Limit strings and other potentially oversized inputs.
- Confirm identifiers and values are valid for the requested action.
- For an
Instance, verify its type, class, and expected location in the DataModel. - Check permissions and context such as distance, character state, and required items.
NaN and positive or negative infinity are valid numeric types, so a basic number check is insufficient. In Luau, value ~= value detects NaN, while math.abs(value) == math.huge detects either infinity.
Keep authority on the server
The server should be the source of truth for game rules, player progression, and critical decisions. For a purchase, the client can request an item, but the server should determine the authoritative price, verify the player's money and relevant context, approve or reject the request, and update the authoritative state.
Combat requests need the same treatment. Before applying damage, the server can validate reported shot positions, obstructions, firing rate, ammunition, weapon state, and whether the reported target is eligible.
Rate-limit client-triggered work
Server logic that clients can trigger can be spammed, so rate limits should be enforced on the server. A token bucket gives each user a limited capacity, consumes a token for an accepted action, and refills tokens at a steady rate. This permits short bursts while limiting sustained request frequency.
Check the limiter before running protected logic, and clear per-player bucket data when a player leaves. Roblox specifically identifies cleanup as a way to prevent unused limiter entries from causing memory leaks.
Release checklist
Before shipping a remote-backed feature:
- Validate every client-controlled argument on the server.
- Reject malformed structures, invalid values,
NaN, and infinity. - Derive permissions, prices, and gameplay state from server-controlled data.
- Treat client-reported hits and purchases as requests requiring verification.
- Enforce server-side rate limits before protected work.
- Remove per-player limiter state when the player leaves.
To keep learning, continue with practical Roblox help on Roblox How.