Security
Garry's Mod addon security audit
Source-level Lua review of Garry's Mod addons for backdoors, unsafe RunString, SQL injection, and unprotected net.Receive handlers. Written findings ranked by exploitability.
Garry's Mod's built-in security model holds up better than its reputation suggests - there's no documented case of an addon breaking out of it entirely on its own. The real, repeatable risk is addon code that willingly hands untrusted data to powerful functions it shouldn't. That exact pattern is how a real, documented backdoor was distributed through the Steam Workshop in the past. Subscriber counts and star ratings are easy to game and tell you nothing about whether the code underneath is safe. Nothing short of reading the source does.
We review addon source code for that pattern and its close relatives: database queries built unsafely from player input, and network message handlers that trust the client more than they should, or have no protection against being flooded.
- Source review for unsafe remote-code-execution patterns and unexplained admin allow-lists
- Database query review for injection risks and unsafe escaping
- Network message handler checklist: permission checks, rate limiting, payload limits
- Written findings ranked by exploitability
Two adjacent patterns are in scope when a review turns them up, even though neither is a separate line item yet: addon-to-addon conflicts that crash the server, and gamemode-level exploits (economy or griefing abuse in DarkRP-style gamemodes, for example) rather than pure network/infra issues. Ongoing addon-reliability monitoring and anti-cheat false-positive tuning are different, subscription-shaped problems we're aware of but don't offer as a standing service yet.
Before
net.Receive("GiveWeapon", function(len, ply)
local wep = net.ReadString()
ply:Give(wep) -- no permission check at all
end)Fixed
net.Receive("GiveWeapon", function(len, ply)
local wep = net.ReadString() -- read before the callback
CAMI.PlayerHasAccess(ply, "giveweapon", function(ok)
if not ok or not IsValid(ply) then return end
ply:Give(wep)
end)
end)Disclaimer: The privilege is registered once at load with CAMI.RegisterPrivilege(MinAccess = "admin"), which is what lets a server owner grant it to a custom moderator group in ULX, SAM, or whatever they run. A plainply:IsAdmin() would also be a valid server-side check - and with no admin mod installed, CAMI falls back to exactly that - but on its own it only recognizes groups inheriting from admin, so it silently locks out the group the owner meant to allow.
Knowledge
Related writing
Also in demand
Setup, performance, and code security
Want this scoped to your server?
Tell us the gamemode, player count, and what is going wrong. Discord, Steam, or email is fine.
Request a consultation