Works with the AI Agents you already use

    Claude CodeClaude CodeCursorCursorCodex CLICodex CLIMuseMuseDotsDots+22 more

    Roblox Security Audit: RemoteEvent Exploits & Data Loss

    3

    Finds the exploits and data-loss bugs in your Roblox/Rojo game, shows the exact line, how it gets abused and how to fix it.

    $5

    Secure checkout via Stripe

    Money-back guarantee

    Converts to your local currency at checkout

    Security scanned
    Roblox Security Audit: RemoteEvent Exploits & Data Loss

    Roblox Security Audit: RemoteEvent Exploits & Data Loss

    Example session with this skill installed

    Audit my Roblox game for exploits before I push the update. The repo is a Rojo project. Focus on security and anything that can lose player data or purchases.

    Also check this reward handler I'm about to ship:

    -- src/server/Rewards.server.luau
    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    local Profiles = require(script.Parent.Profiles)
    
    ReplicatedStorage.Remotes.ClaimReward.OnServerEvent:Connect(function(player, rewardId, amount)
    	local profile = Profiles.Get(player)
    	profile.Coins += amount
    	profile.Claimed[rewardId] = true
    end)
    
    • Read your context and instructions
    • Compiled the roblox security audit
    • Generated the document

    Summary

    Audited every Luau file mapped by default.project.json and every RemoteEvent/RemoteFunction. Report written to audit/luau-security-audit.md. Every finding below was re-read at its cited line before it went in. Excerpt (identifiers renamed, comments trimmed):

    #SeverityCategoryfile:lineEffortTitle
    1CriticalSecuritysrc/server/Rewards.server.luau:5SClient chooses the coin amount in ClaimReward
    2CriticalSecurity / Monetizationsrc/server/Receipts.luau:126MReceipt retry returns PurchaseGranted after a failed save
    3HighSecurity / Datasrc/server/Economy.server.luau:96SUseSkipToken deduction never saved (rejoin duplication)
    4HighSecuritysrc/server/Economy.server.luau:111SNo rate limit or one-time guard on ClaimGift

    [1] Client chooses the coin amount in ClaimReward

    • Severity: Critical · Effort: S · Confidence: High
    • Location: src/server/Rewards.server.luau:5-9
    ReplicatedStorage.Remotes.ClaimReward.OnServerEvent:Connect(function(player, rewardId, amount)
    	local profile = Profiles.Get(player)
    	profile.Coins += amount
    	profile.Claimed[rewardId] = true
    end)
    

    Root cause: amount comes from the client and is added unchecked. rewardId is never checked against a server list or against Claimed.

    Exploit path: an exploit script fires ClaimReward:FireServer("daily", 1e9) once for a billion coins, or fires it in a loop with any rewardId to claim the same reward forever.

    • Proposed fix:
    local REWARDS = { daily = 100, weekly = 750 }
    
    ReplicatedStorage.Remotes.ClaimReward.OnServerEvent:Connect(function(player, rewardId)
    	local value = REWARDS[rewardId]
    	local profile = Profiles.Get(player)
    	if not value or not profile or profile.Claimed[rewardId] then
    		return
    	end
    	profile.Claimed[rewardId] = true
    	profile.Coins += value
    end)
    

    Why this works: the server owns every number. The client only names which reward it wants, and the server decides whether that is allowed and what it is worth. This removes the whole class of "client sends the value" bugs, not just this one.

    • Hardening: log any rewardId that isn't in REWARDS. Only an exploit sends one.

    [2] Receipt retry returns PurchaseGranted after a failed save

    • Severity: Critical · Effort: M · Confidence: High
    • Location: src/server/Receipts.luau:126-128, 188-195
    if profile.Receipts[receiptInfo.PurchaseId] then
    	return Enum.ProductPurchaseDecision.PurchaseGranted
    end
    -- …
    local saved = DataManager.Save(player)
    if not saved then
    	return Enum.ProductPurchaseDecision.NotProcessedYet
    end
    

    Root cause: the receipt is marked in memory before the save. When the save fails, the first call correctly returns NotProcessedYet. But Roblox retries, the retry finds the in-memory mark and returns PurchaseGranted without saving.

    Failure path: player buys a product → DataStore hiccup → retry reports it granted → server shuts down before the autosave → Roblox never redelivers. The player paid Robux and the item is gone.

    Proposed fix: track receipts that were applied but not yet saved. On retry, save again and return PurchaseGranted only once the save succeeds.

    Why this works: PurchaseGranted tells Roblox to stop retrying. It must only be returned once the grant is durable.

    Suggested fix order

    1. Fix #1 and #4 first. Both take minutes and close the open economy exploits.
    2. Fix #2 next, then test it in Studio by forcing DataManager.Save to return false once.
    3. Fix #3 by marking the profile dirty on every deduction, then grep for other spends that never save.

    Next steps

    • Work through the full report in audit/luau-security-audit.md, top to bottom.
    • Re-run the audit after the fixes to confirm the critical findings are gone.

    roblox-security-audit-remoteevent-exploi.pdf

    PDF · document

    Generated

    Example file from a real run - the skill writes it into your workspace.

    Connects securely to your tools. The creator never sees your data.

    About this skill

    Players can send anything to your RemoteEvents. Every argument, every time, as often as they like. So a handler that adds amount from the client is a free-money button, and a ProcessReceipt that returns PurchaseGranted before the save lands means someone paid Robux for nothing.

    This skill goes through a Roblox/Luau codebase looking for exactly that kind of bug and writes one report you can work through from the top.

    What it checks

    It starts from default.project.json, because that's what tells you which scripts actually end up on the client. No Rojo? Save your place from Studio as an .rbxlx file and it reads every script straight out of that instead. Then it lists every RemoteEvent and RemoteFunction and where each one is handled. That list is your whole attack surface.

    From there it looks for unvalidated remote arguments, currency or rewards the client gets to decide, remotes with no rate limit, receipts that aren't idempotent, loadstring, untrusted require calls and admin lists sitting in client-readable code.

    Data loss gets the same attention: deductions that never get saved (the classic rejoin-to-duplicate trick), flags set before a yield, failed loads treated as empty profiles, a missing BindToClose.

    After that it covers the less urgent stuff too. Races, leaked connections, dead code, Rojo mapping drift, missing --!strict, economy logic with no tests.

    Why you can trust the report

    AI audits love to make up line numbers. This one isn't allowed to: a finding only goes in after the agent has re-opened the file and checked that the cited line really says what the finding claims.

    Each finding gives you the file:line with the code quoted as-is, what's wrong, how an attacker would actually use it, and a concrete fix with a short explanation of why it works. That last part matters. Once you understand the fix, you'll spot the same bug elsewhere yourself. Findings are also tagged with effort and confidence, and the report ends with a suggested order for the fixes.

    Tested on a real game

    I ran it on a full obby built for release. It came back with 45 verified findings, 7 of them critical. A receipt retry that treated failed saves as granted. Gamepass IDs that handed out three passes for one purchase. A VIP door that only the client was enforcing. The demo above is taken from that report.

    Good to know

    It's read-only. It writes a single Markdown file and doesn't touch your code or your git history. Works with a Rojo project or a plain Studio place saved as .rbxlx.

    There's nothing to install. You get the SKILL.md your agent follows, a set of ready-made fix patterns it builds its fixes from (server-side validation, rate limiting, an idempotent ProcessReceipt, DataStore saves with retries and BindToClose), and the report template.

    How to use

    Skills on Agensi run inside your AI agent. Copy the prompt, paste it into your agent, and it connects to Agensi and installs this skill for you. If a payment is needed, your agent shows it to you first.

    Reviews

    No reviews yet

    Be one of the first to try it. Every listed skill passes our trust checks below.

    Security scanned

    Passed our 8-point scan before listing

    Fresh listing

    Recently published to Agensi

    Money-back guarantee

    Doesn't do what its page promises? You get your money back.

    Trust & safety

    Security scanned

    Verified clean 8 days ago

    • Passed all security checks, Safe to install

    Listed8 days ago

    What's inside

    Frequently Asked Questions