• How to fix Net exploits?
    17 replies, posted
So i made an addon, and it uses nets to tell the server that that's ready, and when the server has received that net, it spawns an entity. Everything seems fine, but SOME people can use lua scripts to send that very net, and get free ents instantly How could i fix it?
You should always have sanity checks in the serverside part of your addon. Never trust the client, always make sure you check if a message is approved serverside. For example, say you have a car dealer, you send the message that you want to buy a car to the server. The server will check if you have enough money first of all, then it will check the DISTANCE between the player and the dealer. (Don't send the distance from client, just use the player and npc positions serverside and check the distance).
If you could provide your code, that'd be great. Is it just when you do something that the net gets sent? Well, verify that they did that on the server. It's easy to use a stick to hit a button instead of pressing it.
The golden rule is never trust the client. When you develop such systems, you need to think of ways how you could possible circumvent your own system. For example [lua] net.Start("BuyCar) net.WriteUInt(5,6) // This is just our identifier for the car net.WriteFloat(ThePrice) net.SendToServer() [/lua] The problem you have with the above snippet is you don't actually need to send anything in regards to the price. The server should already know the price is. So with something like the above, what you really want is - [lua] net.Start("BuyCar) net.WriteUInt(5,6) //Again, identifier to specify. net.SendToServer() [/lua] You need to make the client interaction as barebones as possible. It doesn't hurt to have validation on the client, but you can [I]not[/I] only have validation on the client. The server needs it as well.
Then, would be that a good idea to kick/ban/whatever the player that sent the net message, and it isn't confirmed by server as "valid"? Oh, and the problem is that you dont BUY something, but CREATE it through a proccess, and i have NO idea how to make the server confirm that it was, indeed, made by the player and not exploited.
[QUOTE=Padle;50267727]Then, would be that a good idea to kick/ban/whatever the player that sent the net message, and it isn't confirmed by server as "valid"? Oh, and the problem is that you dont BUY something, but CREATE it through a proccess, and i have NO idea how to make the server confirm that it was, indeed, made by the player and not exploited.[/QUOTE] Never kick or ban unless its something out of an anticheat, just return it and end the execution If you create it just using the client then something is wrong. Each step you take on creating it, check with the server to tell if it is correct. Please give us more context so we know how to help
cl_init.lua [CODE]include('shared.lua') include('barrel_config.lua') --[[--------------------------------------------------------- Name: Draw Purpose: Draw the model in-game. Remember, the things you render first will be underneath! ---------------------------------------------------------]] function ENT:Draw() -- self.BaseClass.Draw(self) -- We want to override rendering, so don't call baseclass. -- Use this when you need to add to the rendering. self:DrawModel() -- Draw the model. -- Add an example tip. end net.Receive( "MyMenu", function( _, pl ) --jesus christ, thanks Triage! local DermaFrame = vgui.Create("DFrame") local DButton = vgui.Create("DButton", DermaFrame) local DLabel = vgui.Create( "DLabel", DermaFrame ) DLabel:SetPos( 210, 65 ) DLabel:SetText( "Make " .. recipe1 .." to sell." ) DLabel:SetFont("DermaLarge") DLabel:SetSize( 300, 20 ) DButton:SetSize(150,50) DButton:SetText( recipe1 ) DButton:SetPos(50,50) DButton.DoClick = function() DLabel:SetPos( 99999, 999999999 ) local DProgress = vgui.Create( "DProgress", DermaFrame) DProgress:SetPos( 110, 250 ) DProgress:SetSize( 270, 20 ) DProgress:SetFraction( 0 ) local CButton = vgui.Create("CButton", DermaFrame) DButton:SetSize(150,50) DButton:SetText( "Cook!" ) DButton:SetPos(175,50) DButton.DoClick = function() DProgress:SetFraction(DProgress:GetFraction() + 0.05) processofcook = DProgress:GetFraction() if processofcook >= 0.99 then print( "we made something" ) net.Start("somethingactuallyhappened") net.SendToServer() end end end DermaFrame:Center() --Position on players screen. [X,Y] DermaFrame:SetSize(500,350) --Size of the frame. [X,Y] DermaFrame:SetTitle("Cooking Menu") --Title of the frame. DermaFrame:SetVisible(true) --Visible by player? [true=Visible, false=Invisible] DermaFrame:SetDraggable(true) --Draggable by player? [true=Can, flase=Can Not] DermaFrame:ShowCloseButton(true) --Show the close button? [true=Show, false=Dont Show] DermaFrame:SetBackgroundBlur(barrelBlur) --Make everything behind the frame fade to blur? [true=yes, false=no] DermaFrame:SetDeleteOnClose(true) --Delete frame on close? [true = yes; false = no] DermaFrame:MakePopup() --Make the frame popup. end) [/CODE] init.lua [CODE] AddCSLuaFile( "cl_init.lua" ) -- Make sure clientside AddCSLuaFile( "shared.lua" ) -- and shared scripts are sent. AddCSLuaFile( "barrel_config.lua" ) include('shared.lua') util.AddNetworkString("MyMenu") util.AddNetworkString("somethingactuallyhappened") function ENT:Initialize() self:SetModel( "models/props_c17/woodbarrel001.mdl" ) self:PhysicsInit( SOLID_VPHYSICS ) -- Make us work with physics, self:SetMoveType( MOVETYPE_VPHYSICS ) -- after all, gmod is a physics self:SetSolid( SOLID_VPHYSICS ) -- Toolbox self:SetUseType( SIMPLE_USE ) local phys = self:GetPhysicsObject() if (phys:IsValid()) then phys:Wake() end end net.Receive("somethingactuallyhappened", function(ply) local moonshine = ents.Create( "something" ) local stovePos = self:GetPos() local plyPos = ply:GetPos() if plyPos:Distance(stovePos) <= 100 then return end if ( !IsValid( something ) ) then return end // Check whether we successfully made an entity, if not - bail moonshine:SetPos( barrelPos + Vector(0,0,50) ) moonshine:Spawn() end) function ENT:AcceptInput( n, a, c ) if n == "Use" and c:IsPlayer() then net.Start("MyMenu") net.Send(c) end end function ENT:Think() barrelPos = self:GetPos() end [/CODE] Nothing in shared.lua
What happens when I spam "lua_run_cl net.Start("somethingactuallyhappened") net.SendToServer()" in the console? Assume any net message can be sent in any way at any time.
[QUOTE=LegoGuy;50267780]What happens when I spam "lua_run_cl net.Start("somethingactuallyhappened") net.SendToServer()" in the console? Assume any net message can be sent in any way at any time.[/QUOTE] Every time you do it, the entity "something" spawns on top of the barrel. Yup. Edited: Almost figured out how to do it...
[QUOTE=Padle;50267784]Every time you do it, the entity "something" spawns on top of the barrel. Yup.[/QUOTE] Knowing this, wouldn't it make sense for the server to do the progressing and send the percentage back to the client afterwards?
Okay, you need to be networking the var 'processofcook' and be verifying if it's correct or not. edit: i'll fix it for you, just give me like 5 minutes [editline]6th May 2016[/editline] okay, give this a go (backup your old stuff first) new cl_init.lua: [lua] include('shared.lua') include('barrel_config.lua') --[[--------------------------------------------------------- Name: Draw Purpose: Draw the model in-game. Remember, the things you render first will be underneath! ---------------------------------------------------------]] function ENT:Draw() -- self.BaseClass.Draw(self) -- We want to override rendering, so don't call baseclass. -- Use this when you need to add to the rendering. self:DrawModel() -- Draw the model. -- Add an example tip. end [/lua] new init.lua: [lua] AddCSLuaFile( "cl_init.lua" ) -- Make sure clientside AddCSLuaFile( "shared.lua" ) -- and shared scripts are sent. AddCSLuaFile( "barrel_config.lua" ) include('shared.lua') util.AddNetworkString("MyMenu") util.AddNetworkString("somethingactuallyhappened") function ENT:Initialize() BarrelsAlive = BarrelsAlive + 1 self.progresstime = 0 self:SetModel("models/props_c17/woodbarrel001.mdl") self:PhysicsInit( SOLID_VPHYSICS ) -- Make us work with physics, self:SetMoveType( MOVETYPE_VPHYSICS ) -- after all, gmod is a physics self:SetSolid( SOLID_VPHYSICS ) -- Toolbox self:SetUseType( SIMPLE_USE ) local phys = self:GetPhysicsObject() if (phys:IsValid()) then phys:Wake() end end function ENT:AcceptInput( n, a, c ) if n == "Use" and c:IsPlayer() then net.Start("MyMenu") net.WriteEntity(self) net.WriteUInt(self.progresstime, 16) net.Send(c) end end function ENT:Think() barrelPos = self:GetPos() end [/lua] now make a new file in lua/autorun, and put this code in [lua] if SERVER then BarrelsAlive = 0 timer.Create("addbarrelprogress", 1, 0, function() if BarrelsAlive == 0 then return end for k,v in pairs(ents.FindByClass("put your entity name in here")) do if v.progresstime then if v.progresstime != 1 then v.progresstime = v.progresstime + 0.1 end end end end ) net.Receive("somethingactuallyhappened", function(ply) if net.ReadEntity() then local ent = net.ReadEntity() end if ent:GetClass() != "put your ent name in here" then return end // wrong entity if ent.progresstime != 1 then return end // wrong progress (1 = complete) local moonshine = ents.Create("something") moonshine:SetPos( ent:GetPos() + Vector(0,0,50) ) local plyPos = ply:GetPos() if plyPos:Distance(v:GetPos()) <= 100 then return end moonshine:Spawn() end ) end if CLIENT then net.Receive( "MyMenu", function( _, pl ) --jesus christ, thanks Triage! local ent = net.ReadEntity() local progresstime = net.ReadUInt(16) local DermaFrame = vgui.Create("DFrame") local DButton = vgui.Create("DButton", DermaFrame) local DLabel = vgui.Create( "DLabel", DermaFrame ) DLabel:SetPos( 210, 65 ) DLabel:SetText( "Make " .. recipe1 .." to sell." ) DLabel:SetFont("DermaLarge") DLabel:SetSize( 300, 20 ) DButton:SetSize(150,50) DButton:SetText( recipe1 ) DButton:SetPos(50,50) DButton.DoClick = function() DLabel:SetPos( 99999, 999999999 ) local DProgress = vgui.Create( "DProgress", DermaFrame) DProgress:SetPos( 110, 250 ) DProgress:SetSize( 270, 20 ) DProgress:SetFraction( 0 ) local CButton = vgui.Create("CButton", DermaFrame) DButton:SetSize(150,50) DButton:SetText( "Cook!" ) DButton:SetPos(175,50) DButton.DoClick = function() DProgress:SetFraction(progresstime) if progresstime >= 1 then net.Start("somethingactuallyhappened") net.WriteEntity(ent) net.SendToServer() end DermaFrame:Center() --Position on players screen. [X,Y] DermaFrame:SetSize(500,350) --Size of the frame. [X,Y] DermaFrame:SetTitle("Cooking Menu") --Title of the frame. DermaFrame:SetVisible(true) --Visible by player? [true=Visible, false=Invisible] DermaFrame:SetDraggable(true) --Draggable by player? [true=Can, flase=Can Not] DermaFrame:ShowCloseButton(true) --Show the close button? [true=Show, false=Dont Show] DermaFrame:SetBackgroundBlur(barrelBlur) --Make everything behind the frame fade to blur? [true=yes, false=no] DermaFrame:SetDeleteOnClose(true) --Delete frame on close? [true = yes; false = no] DermaFrame:MakePopup() --Make the frame popup. end ) end [/lua] [b] edit the parts where it says 'put your entity name in here' - i didn't know the name of the entity [/b] (i made a new file because in your init.lua and cl_init.lua, each new instance of the entity was making the net.receive callback each time. it's better to just make one of them) let me know how it goes. if things are wrong, i'll try again :) EDIT 2: made a mistake. in the lua/autorun file, go to [lua] net.Receive("somethingactuallyhappened", function(ply) if net.ReadString() then [/lua] change the net.ReadString() to net.ReadEntity()
[QUOTE=tyguy;50267796]Okay, you need to be networking the var 'processofcook' and be verifying if it's correct or not. edit: i'll fix it for you, just give me like 5 minutes [editline]6th May 2016[/editline] okay, give this a go (backup your old stuff first) new cl_init.lua: [lua] include('shared.lua') include('barrel_config.lua') --[[--------------------------------------------------------- Name: Draw Purpose: Draw the model in-game. Remember, the things you render first will be underneath! ---------------------------------------------------------]] function ENT:Draw() -- self.BaseClass.Draw(self) -- We want to override rendering, so don't call baseclass. -- Use this when you need to add to the rendering. self:DrawModel() -- Draw the model. -- Add an example tip. end [/lua] new init.lua: [lua] AddCSLuaFile( "cl_init.lua" ) -- Make sure clientside AddCSLuaFile( "shared.lua" ) -- and shared scripts are sent. AddCSLuaFile( "barrel_config.lua" ) include('shared.lua') util.AddNetworkString("MyMenu") util.AddNetworkString("somethingactuallyhappened") function ENT:Initialize() BarrelsAlive = BarrelsAlive + 1 self.progresstime = 0 self:SetModel("models/props_c17/woodbarrel001.mdl") self:PhysicsInit( SOLID_VPHYSICS ) -- Make us work with physics, self:SetMoveType( MOVETYPE_VPHYSICS ) -- after all, gmod is a physics self:SetSolid( SOLID_VPHYSICS ) -- Toolbox self:SetUseType( SIMPLE_USE ) local phys = self:GetPhysicsObject() if (phys:IsValid()) then phys:Wake() end end function ENT:AcceptInput( n, a, c ) if n == "Use" and c:IsPlayer() then net.Start("MyMenu") net.WriteEntity(self) net.WriteUInt(self.progresstime, 16) net.Send(c) end end function ENT:Think() barrelPos = self:GetPos() end [/lua] now make a new file in lua/autorun, and put this code in [lua] if SERVER then BarrelsAlive = 0 timer.Create("addbarrelprogress", 1, 0, function() if BarrelsAlive == 0 then return end for k,v in pairs(ents.FindByClass("put your entity name in here")) do if v.progresstime then if v.progresstime != 1 then v.progresstime = v.progresstime + 0.1 end end end end ) net.Receive("somethingactuallyhappened", function(ply) if net.ReadEntity() then local ent = net.ReadEntity() end if ent:GetClass() != "put your ent name in here" then return end // wrong entity if ent.progresstime != 1 then return end // wrong progress (1 = complete) local moonshine = ents.Create("something") moonshine:SetPos( ent:GetPos() + Vector(0,0,50) ) local plyPos = ply:GetPos() if plyPos:Distance(v:GetPos()) <= 100 then return end moonshine:Spawn() end ) end if CLIENT then net.Receive( "MyMenu", function( _, pl ) --jesus christ, thanks Triage! local ent = net.ReadEntity() local progresstime = net.ReadUInt(16) local DermaFrame = vgui.Create("DFrame") local DButton = vgui.Create("DButton", DermaFrame) local DLabel = vgui.Create( "DLabel", DermaFrame ) DLabel:SetPos( 210, 65 ) DLabel:SetText( "Make " .. recipe1 .." to sell." ) DLabel:SetFont("DermaLarge") DLabel:SetSize( 300, 20 ) DButton:SetSize(150,50) DButton:SetText( recipe1 ) DButton:SetPos(50,50) DButton.DoClick = function() DLabel:SetPos( 99999, 999999999 ) local DProgress = vgui.Create( "DProgress", DermaFrame) DProgress:SetPos( 110, 250 ) DProgress:SetSize( 270, 20 ) DProgress:SetFraction( 0 ) local CButton = vgui.Create("CButton", DermaFrame) DButton:SetSize(150,50) DButton:SetText( "Cook!" ) DButton:SetPos(175,50) DButton.DoClick = function() DProgress:SetFraction(progresstime) if progresstime >= 1 then net.Start("somethingactuallyhappened") net.WriteEntity(ent) net.SendToServer() end DermaFrame:Center() --Position on players screen. [X,Y] DermaFrame:SetSize(500,350) --Size of the frame. [X,Y] DermaFrame:SetTitle("Cooking Menu") --Title of the frame. DermaFrame:SetVisible(true) --Visible by player? [true=Visible, false=Invisible] DermaFrame:SetDraggable(true) --Draggable by player? [true=Can, flase=Can Not] DermaFrame:ShowCloseButton(true) --Show the close button? [true=Show, false=Dont Show] DermaFrame:SetBackgroundBlur(barrelBlur) --Make everything behind the frame fade to blur? [true=yes, false=no] DermaFrame:SetDeleteOnClose(true) --Delete frame on close? [true = yes; false = no] DermaFrame:MakePopup() --Make the frame popup. end ) end [/lua] [b] edit the parts where it says 'put your entity name in here' - i didn't know the name of the entity [/b] (i made a new file because in your init.lua and cl_init.lua, each new instance of the entity was making the net.receive callback each time. it's better to just make one of them) let me know how it goes. if things are wrong, i'll try again :) EDIT 2: made a mistake. in the lua/autorun file, go to [lua] net.Receive("somethingactuallyhappened", function(ply) if net.ReadString() then [/lua] change the net.ReadString() to net.ReadEntity()[/QUOTE] There were plenty of unfinished functions and the progress bar doesnt go up. I'll fix this in like 3 minutes, but you told me to tell you how it goes :pudge:
[QUOTE=Padle;50268066]There were plenty of unfinished functions and the progress bar doesnt go up. I'll fix this in like 3 minutes, but you told me to tell you how it goes :pudge:[/QUOTE] unfinished functions? is the progress bar meant to go up?
[QUOTE=tyguy;50268236]unfinished functions? is the progress bar meant to go up?[/QUOTE] yes, and there are functions that you didnt "end"
[QUOTE=Padle;50268361]yes, and there are functions that you didnt "end"[/QUOTE] oh, just add those ends then. the progress bar moving should be up to you, i (hopefully) did what you wanted and stopped net exploits
[QUOTE=tyguy;50268463]oh, just add those ends then. the progress bar moving should be up to you, i (hopefully) did what you wanted and stopped net exploits[/QUOTE] Well, the point of me even creating this wasnt to make an addon, but rather learn more about nets, entities, etc. You did help me make this entity, and i know some more stuff now because of all of you guys :p Thanks!
[QUOTE=Padle;50268474]Well, the point of me even creating this wasnt to make an addon, but rather learn more about nets, entities, etc. You did help me make this entity, and i know some more stuff now because of all of you guys :p[/QUOTE] "Thanks for taking time out of your life to help me, tyguy! It may not have worked as I intended it to, but at least you tried to help!"
[QUOTE=tyguy;50268734]"Thanks for taking time out of your life to help me, tyguy! It may not have worked as I intended it to, but at least you tried to help!"[/QUOTE] "Thanks for taking time out of your life to help me, tyguy! It may not have worked as I intended it to, but you tried to help and i learnt something new about coding today!" [B]Edit:[/B] Oh, and you actually DID help me, if you are wondering about that... [I][DEL]did i do something wrong?[/DEL][/I]
Sorry, you need to Log In to post a reply to this thread.