Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/brockmartin/roblox-game-skill/llms.txt

Use this file to discover all available pages before exploring further.

The Security Audit workflow systematically identifies every vulnerability that would let an exploiter manipulate your game — from RemoteEvent handlers that accept unvalidated data to server logic accidentally placed in ReplicatedStorage. It works through eight steps: mapping your attack surface, verifying argument validation, auditing client trust, checking data exposure, reviewing rate limits, generating a severity report, applying hardened code, and re-verifying. Run this workflow before any public launch, after adding new systems, or whenever the Publish Checklist flags security items as incomplete. Trigger: “Run a security audit”, “harden my game”, “check for exploits”, or triggered from the Publish Checklist.
1

Remote Surface Scan

Claude maps every RemoteEvent and RemoteFunction in the project to establish the full attack surface.
Uses get_project_structure to locate all scripts, then grep_scripts to search for: RemoteEvent, RemoteFunction, BindableEvent, BindableFunction, :FireServer(, :FireClient(, :FireAllClients(, :InvokeServer(, :InvokeClient(.The output is a complete remote inventory: name, location, direction (client→server or server→client), and purpose.
2

Validation Check

For every OnServerEvent and OnServerInvoke handler, Claude verifies four layers of defense.2a. Type checking — Every argument from the client must be type-checked with typeof() before use. Reject the entire request if any argument fails — do not attempt to coerce.
-- GOOD: reject on type mismatch
RemoteEvent.OnServerEvent:Connect(function(player, itemId, quantity)
    if typeof(itemId) ~= "string" then return end
    if typeof(quantity) ~= "number" then return end
    if quantity ~= math.floor(quantity) then return end  -- must be integer
    -- proceed safely
end)
2b. Range validation — Numeric values must be bounds-checked (e.g., quantity between 1 and 99). String values must be length-checked. Enum-like values must match a whitelist.2c. Cooldowns — Rate limiting must exist to prevent spam-firing. The pattern: a per-player timestamp table with a minimum interval.
local lastFire = {}

RemoteEvent.OnServerEvent:Connect(function(player, ...)
    local now = tick()
    if lastFire[player] and now - lastFire[player] < 0.5 then return end
    lastFire[player] = now
    -- proceed
end)
2d. Authorization — The player must be verified to have permission for the requested action. Does the player own the item they are equipping? Are they in the correct game state? Never trust the client to report its own permissions.
3

Client Trust Audit

Claude searches for game logic running on the client that should only exist on the server.
These patterns are the most exploited vulnerabilities in Roblox games. An exploiter can fire any RemoteEvent with any arguments — if the server trusts client-provided values, the game is compromised.
Red flags Claude scans for:
PatternWhy It’s Dangerous
Client script setting leaderstats valuesExploiter sets their own currency to any number
Client computing damage and sending the resultExploiter sends one-shot damage
Client adding items to inventory and syncingExploiter duplicates any item
Client setting its own CFrame via a remoteExploiter teleports anywhere
Client telling server a purchase succeededExploiter gets items for free
In Full/Standard modes, grep_scripts searches client scripts (StarterPlayerScripts, StarterGui) for: leaderstats, Currency, Coins, Gems, Gold, Damage, Health — any place where the client computes a value and fires it to the server.The correct pattern: the client sends intent, the server validates and acts.
-- WRONG: client sends a computed result
-- (client script)
local damage = calculateDamage(weapon, target)  -- exploiter controls this
DamageRemote:FireServer(target, damage)

-- CORRECT: client sends an intent; server computes everything
-- (client script)
AttackRemote:FireServer(targetCharacter)

-- (server script)
AttackRemote.OnServerEvent:Connect(function(player, targetCharacter)
    -- validate target is a real character in the workspace
    if not targetCharacter or not targetCharacter:IsDescendantOf(workspace) then return end
    local targetHumanoid = targetCharacter:FindFirstChildOfClass("Humanoid")
    if not targetHumanoid then return end

    -- server computes damage from server-owned weapon data
    local playerData = DataManager.getData(player)
    local damage = calculateDamage(playerData.weaponStats)
    targetHumanoid:TakeDamage(damage)
end)
4

Data Exposure Check

Claude audits what data is visible or accessible to clients.ReplicatedStorage — Everything here is visible to all clients. Claude checks for:
  • Admin keys, API tokens, or secrets (must never be here)
  • Server configuration that reveals exploitable mechanics (exact drop rates, spawn timers)
  • ModuleScripts containing server logic (must live in ServerScriptService or ServerStorage)
Remote payloads — Claude reviews what is sent via FireClient / FireAllClients:
  • Other players’ private data (inventory, currency, stats) must not be broadcast to everyone
  • Internal IDs or keys that could be replayed in forged requests
Attributes and value objects — Attributes set on replicated instances (Players, Characters, Workspace objects) are readable by all clients. Sensitive values must not be stored as Attribute, IntValue, or StringValue on replicated instances.
A ModuleScript placed in ReplicatedStorage can be require()d by any client. Any logic it contains — including server-side formulas, anti-cheat thresholds, or data keys — is fully visible to exploiters.
5

Rate Limiting Check

Claude verifies that every server-side remote handler has a per-player cooldown.
Action TypeRecommended Minimum Interval
Combat actions0.1–0.5 seconds
Economy actions (buy/sell)0.5–1.0 seconds
Chat/social actions1.0–3.0 seconds
UI/cosmetic actions0.2–0.5 seconds
Players who exceed rate limits should be warned or kicked — not just silently ignored — so that exploit attempts are detectable in logs.RemoteFunction abuseOnServerInvoke is synchronous and blocks the calling thread. An exploiter can spam-invoke to exhaust server threads. Prefer RemoteEvents wherever possible; if RemoteFunctions are necessary, apply aggressive rate limiting.Payload size validation — Large tables sent via remotes can be used for denial-of-service. Validate table size and depth before iterating.
6

Vulnerability Report

Claude compiles all findings into a prioritized security report.
## Security Audit Report

### Critical (actively exploitable — fix immediately)
- [Finding]: [File:Line] — [Description, attack vector, and impact]
  Fix: [Specific remediation]

### High (exploitable with moderate effort)
- [Finding]: [File:Line] — [Description, attack vector, and impact]
  Fix: [Specific remediation]

### Medium (defense-in-depth gaps)
- [Finding]: [File:Line] — [Description and impact]
  Fix: [Specific remediation]

### Low (best practice improvements)
- [Finding]: [File:Line] — [Description]
  Fix: [Specific remediation]

### Summary
- Total remotes audited:        X
- Remotes missing validation:   X
- Client-trusted logic found:   X
- Data exposure issues:         X
- Rate limiting gaps:           X
SeverityCriteria
CriticalExploiter can directly manipulate currency, items, or stats — or crash the server. No validation on a sensitive remote.
HighExploiter gains unfair competitive advantage or accesses other players’ private data.
MediumMissing defense-in-depth layers (cooldowns exist but no type checking, or vice versa).
LowBest-practice gaps that do not currently create an exploit path but weaken overall security posture.
7

Apply Hardened Code

For each vulnerability, Claude provides or directly applies the fix.Reusable validation module:
-- ServerStorage/Modules/RemoteValidator.lua
local Validator = {}

function Validator.validateArgs(args, schema)
    for i, expected in ipairs(schema) do
        local arg = args[i]
        if typeof(arg) ~= expected.type then return false end
        if expected.range and (arg < expected.range[1] or arg > expected.range[2]) then
            return false
        end
        if expected.maxLength and typeof(arg) == "string" and #arg > expected.maxLength then
            return false
        end
        if expected.whitelist and not table.find(expected.whitelist, arg) then
            return false
        end
    end
    return true
end

return Validator
Usage in a handler:
local Validator = require(ServerStorage.Modules.RemoteValidator)

PurchaseRemote.OnServerEvent:Connect(function(player, itemId, quantity)
    local valid = Validator.validateArgs(
        { itemId, quantity },
        {
            { type = "string",  maxLength = 64,
              whitelist = ItemCatalog.getIds() },
            { type = "number",  range = {1, 99} },
        }
    )
    if not valid then return end
    -- safe to proceed
end)
Fix categories Claude addresses:
  1. Validation wrappers — reusable module as above
  2. Rate limiting module — centralized per-player cooldown management
  3. Server-authoritative rewrites — moving client-trusted logic to the server
  4. Data relocation — moving sensitive modules from ReplicatedStorage to ServerStorage
Fixes are applied directly if MCP write access is available. Otherwise, the complete corrected code for each file is provided.
8

Re-Verify

After fixes are applied, Claude re-runs the audit to confirm all issues are resolved.
  1. Repeat the Remote Surface Scan (Step 1) to confirm no new unprotected remotes were introduced
  2. Repeat the Validation Check (Step 2) on all modified handlers
  3. Confirm all Critical and High findings are resolved
  4. Document any accepted Medium/Low risks with written justification
## Re-Verification Results

- Findings resolved:          X/Y
- Remaining accepted risks:   X  (with justifications)
- New issues introduced:      0
- Security posture:           [Hardened / Improved / Unchanged]
For reference implementations of every validation and rate-limiting pattern covered in this workflow, see Security Hardening.

Build docs developers (and LLMs) love