Protect net message

Net message exploits are one of the most common exploits in gLUA. This is because the programmers have to secure net.Receive functions themselves.

Good Example

The following is a code snippet (the serverside net.Receive function) from an armory addon. With this the police players can retrieve selected weapons from their armory.

local validWeapons = {
  ["weapon_m42"] = true,
net.Receive("police_armory_retrieve", function(len, ply)
  local ent = net.ReadEntity()
  local weaponClass = net.ReadString()

  --[1] spam delay
  if not ply.armoryTimeout then ply.armoryTimeout = 0 end
  if ply.armoryTimeout > CurTime() then return end
  ply.armoryTimeout = CurTime() + 10

  --[2] check team
  if ply:Team() ~= TEAM_POLICE then return end

  --[3] check entity and distance
  if not IsValid(ent) then return end
  if ent:GetClass() ~= "sent_police_armory" then return end
  if ply:GetPos():Distance(ent:GetPos())) > 512 then return end

  --[4] check requested weapon
  if not validWeapons[weaponClass] then return end

  --do stuff

This code checks everything that needs to be checked before giving the sending player his weapon.
The first check (code block) is against net spam. You can only retrieve a weapon from the police armory every 10 seconds.
The second code block checks if the player is even in the right team to retrieve things from the police armory.
The third block checks the entity. Did the player send a valid entity? Is it a police armory? Is he close enough to interact with it? (we need a valid entity to calculate the distance between it and the player)
The last check is about the weapon the player wants to retrieve. We shouldn't let the player take out any weapon they want, this could lead to exploits too.

Now for a bad example.

Bad example

Please remember: THIS IS A BAD EXAMPLE!

net.Receive("police_armory_retrieve", function(len, ply)
  local officer = net.ReadEntity()
  local weaponClass = net.ReadString()

The code example above not only gives any player that sends the net message any weapon they requested. You can send any player with the net message and he receives the weapon you sent.
This means that you, for example, can give everyone on the server a physgun with the following code:

for k,v in pairs(player.GetAll()) do

This is, ofcourse, not good and should be avoided at all costs.


To write non-exploitable net.Receive functions you have to look out for the following:

Ofcourse you can do checks on the client too, but never do checks only on the client. Either server-only or server and client.