What is it:
SecureRemote is a tiny wrapper around RemoteEvent/RemoteFunction that adds the boring but important parts: schema validation, rate limiting with cooldown/backoff, idempotency via __reqId, duplicate-content blocking, minimal interval between accepts, unknown-key rejection, and callback timeout guards.
Why use it:
- Fewer exploit surfaces: only fields you allow, within sizes you allow.
- Less spam: per-player and per-action throttling, dedupe, and single-flight.
- Fewer hangs: server callbacks are wrapped with a timeout.
- Cleaner code: one place to configure policy, same shape for responses.
Features:
- Schema validation (type/required/min/max/enum/regex/nested/defaults)
- Per-player and per-action rate limits with cooldown and optional backoff
- Idempotency window (
__reqId) - Duplicate-content dedupe window
- Minimal interval between accepts (anti auto-click)
- Optional single-flight lock (rejects overlapping requests)
- Reject unknown keys (on by default)
- Callback timeout guard
- Simple stats: ok/rejected/rateLimited/callbackError
- Optional permission gate (
SetCanInvoke)
Install:
- Require from server script
Example (Server):
local SecureRemote = require(game.ServerScriptService.SecureRemote)
local BuyItem = SecureRemote.new("BuyItem", game.ReplicatedStorage, "Function", {
minIntervalSec = 0.2, -- reject ultra-fast repeat clicks
rateLimit = 5,
rateWindow = 1,
cooldownAfterBurst = 2,
idempotencyWindow = 10,
})
local schema = {
itemId = { type = "string", required = true, allowed = { "Sword", "Shield", "Potion" } },
amount = { type = "number", min = 1, max = 5, default = 1 },
attributes = {
type = "table",
schema = {
rarity = { type = "string", allowed = { "Common", "Rare", "Epic" }, default = "Common" },
enchanted = { type = "boolean", default = false },
},
},
}
BuyItem:SetCanInvoke(function(player, data)
-- Example: block guests, region, game-mode, etc.
return true
end)
BuyItem:OnServerFunction(schema, function(player, data, trace)
-- Do your logic here
return {
success = true,
message = "OK",
itemBought = data.itemId,
quantity = data.amount,
paid = 100,
trace = trace,
}
end)
Example (Client):
local HttpService = game:GetService("HttpService")
local BuyItem = game.ReplicatedStorage:WaitForChild("BuyItem")
local req = {
__reqId = HttpService:GenerateGUID(false), -- idempotency
itemId = "Sword",
amount = 1,
attributes = { rarity = "Epic", enchanted = true },
}
local res = BuyItem:InvokeServer(req)
if res and res.success then
print("Bought:", res.itemBought)
else
warn(res and res.code, res and (res.reason or res.message))
end
- Change what you want. No credit required
- Created by steakzetaim. If it helped your project or saved you time, a follow is appreciated