How could I make this script more secure?

I want this client script to be more secure, so exploiters have a hard time messing with it.
I do not know how to do that besides using remotes and GUIDS.
Going here.

Code
--!strict
local ModuleQ = require(script.QuestionsAndAnswers)
local MainFrameQ = script.Parent.MainFrameQuestions

local function _init()
	local Success,Ret = pcall(function()
		for _,tbl in next,ModuleQ do
			local new = MainFrameQ.MainClip.Template

			if not MainFrameQ.MainClip:FindFirstChild(tbl[1]) then
				local a = new:Clone()
				a.Title.Text = tbl[1]
				a.Answer.Text = tbl[2]
				a.Name = tbl[1]
				a.Parent = MainFrameQ.MainClip
				a.Visible = true
			end
		end
		
		local search = MainFrameQ.Search
		
		search.FocusLost:Connect(function(enterPressed)
			local text = search.Text

			if text ~= '' and text ~= nil then
				if enterPressed then
					local foundMatch = false

					for _, tbl in next, ModuleQ do
						if string.find(text:lower(), tbl[3]:lower(), 1) then
							local matchedFrame = MainFrameQ.MainClip:FindFirstChild(tbl[1])

							if matchedFrame then

								for _, child in next, MainFrameQ.MainClip:GetChildren() do
									if child:IsA('Frame') and child.Name:lower() ~= 'template' then
										child.Visible = false
									end
								end


								matchedFrame.Visible = true
								foundMatch = true
							end
							break
						end
					end


					if not foundMatch then
						for _, child in next, MainFrameQ.MainClip:GetChildren() do
							if child:IsA('Frame') and child.Name:lower() ~= 'template' then
								child.Visible = true
							end
						end
					end
				end
			end
			
			if text == '' then
				for _, child in next, MainFrameQ.MainClip:GetChildren() do
					if child:IsA('Frame') and child.Name:lower() ~= 'template' then
						child.Visible = true
					end
				end
			end
		end)

		
		local Lib = game.ReplicatedStorage.Shared.UI.Library
		local GB = require(Lib.GenButton)
		GB.new(
			script.Parent.ToggleUi
		)
		GB.new(
			script.Parent.ToggleQuestions
		)
		script.Parent.ToggleQuestions.Activated:Connect(function()
			if not game.SoundService:FindFirstChild(`Clicked`) then
				local new = game.ReplicatedStorage.Sounds.ClickSound:Clone()
				new.Parent = game.SoundService
				new:Play()
				
				new.Ended:Connect(function()
					task.spawn(function()
						new:Destroy()
					end)
				end)
			end
			local att = script.Parent.ToggleQuestions:GetAttribute('Override')
			
			if att then
				MainFrameQ.Visible = not MainFrameQ.Visible
			end
		end)
			script.Parent.ToggleUi.Activated:Connect(function()
				if not game.SoundService:FindFirstChild(`Clicked`) then
					local new = game.ReplicatedStorage.Sounds.ClickSound:Clone()
					new.Parent = game.SoundService
					new:Play()

					new.Ended:Connect(function()
						task.spawn(function()
							new:Destroy()
						end)
					end)
				end
			for _,frame in next,script.Parent:GetChildren() do
				if frame:IsA('Frame') then
					frame.Visible = false
				end
				
				if frame:IsA('TextButton') or frame:IsA('ImageButton') then
					if frame.Name:lower() ~= 'toggleui' then
						local att = frame:GetAttribute('Override')
					
						if att then
							att = not att
						end
					
						frame.Visible = not frame.Visible
					end
				end
			end
		end)
	end)
	
	local httpmodule = require(game.ReplicatedStorage.Utility.httpText)
	
	httpmodule(
		'Bold',
		script.Parent.ToggleQuestions,
		script.Parent.ToggleQuestions.RichText
	)
	httpmodule(
		'Bold',
		script.Parent.ToggleUi,
		script.Parent.ToggleUi.RichText
	)
	httpmodule(
		'Underline',
		script.Parent.ToggleUi,
		script.Parent.ToggleUi.RichText
	)
	httpmodule(
		'Underline',
		script.Parent.ToggleQuestions,
		script.Parent.ToggleQuestions.RichText
	)
	
	return Success,Ret
end


local Success,Return = _init()

if Success then
	warn('_init successfully ran and loaded all HUD elements | ',script:GetFullName())
else
	error(tostring(Return) or Return,5)
end
1 Like

To address your question about making the client-side script more secure, unfortunately, there is no foolproof solution as long as exploiters have access to the client. However, you can try using encryption to randomize all lines of code. I noticed a few lines that you can improve. One method for added security is to randomize the names of client-sided categories, such as ReplicatedStorage, Lighting, Workspace, etc. This method sets the names of these categories to random decimal numbers, making it harder for inexperienced exploiters to access them. Additionally, you will need to call upon these categories by using game:GetService("InsertServiceNameHere") instead of game."InsertServiceNameHere."

An example:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Set a random seed based on time to ensure randomness each time the server starts
math.randomseed(tick())
-- Generate a random decimal between 0 and 1 by dividing by a large number
local randomDecimal = math.random() + math.random(1, 1000000) / 1000000
-- Set the new randomized name of ReplicatedStorage
ReplicatedStorage.Name = tostring(randomDecimal)

How would I then access ReplicatedStorage from other scripts?

GetService returns the service based on its class not the name if it makes sense

1 Like

Replace all calls to the ReplicatedStorage with:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
1 Like

Is there a way to do this automatically for everywhere Service, or you need to individually re-name each Service.

As in, is there a way to do something like game:GetServices for example (Which would return every Service)?

1 Like

game:GetChildren() will get all the services

3 Likes
for _, service in ipairs(game:GetChildren()) do
	service.Name = tostring(math.random())
end
2 Likes

Thanks, but you don’t need ipairs anymore but thanks for the script appreciate it

1 Like

Would you use pairs then?

pairs and ipairs | Documentation - Roblox Creator Hub

1 Like

Neither, the below works fine

for _, Service in game:GetChildren() do
	Service.Name = tostring(math.random())
end
2 Likes

There are a lot of methods of approaching this which will be included down below

  1. Anti Exploit
Summary

Add functions that can be called through remotes (before they are called to the server). Integrity check multiple things. This can be very complex so I wouldn’t recommend.

  1. Add random checks which exploiters could change
  2. Store the remote as a variable and setting its parent to nil
    Example:
local YourRemote = game:GetService("ReplicatedStorage").Remote;
YourRemote.Parent = nil;

Please take note this can be obtained through exploits if they have debug.getlocal or even getgc
To get around this, constantly check if anything on the Remote was changed via Changed if anything was, kick the player or crash them if they did not disconnect.

  1. Server Sided Verification
Summary
  1. Instead of managing all Parameters on the client, you can predefine remotes to do certain action on the server (add checks to see if a user is calling it to often). This can remove the result of parameters. Although if you need them, stick with your current method.
  2. Encode your messages, you can use some kind of encoding that isn’t easy to decode or identify
  3. Add certain variables in your messages that will never change or are easily shared across the server and client. It could be a value in Replicated Storage that could change every few seconds.

To make it a lot harder in general, have a thread going in the background that constantly sets your core components instances’ names to something completely random. I recommend the \0x (Correct me if I’m wrong on the formatting) or any kind of byte-character.

If you need to do some penetration testing go use RbxStu V1 or V2
Forum: RbxStu Highly recommend it is a great resource to use.

2 Likes