How do I securely send information to the server I am teleporting players to?

Hey developers,

I am trying to make so players can vote for a certain map in a lobby place and then get teleported to the gameplay place which suppose to receive the voting results and use them. How would I do that securely?

I thought of using GetTeleportSetting() but its designed for client only and using it would be a security risk and vulnerability. Then I thought about using MessagingService but I am not sure on how I would retrieve JobId of the server that I am teleporting players to (perhaps by using TeleportPartyAsync()?), and how to know when the server is ready to receive the message?

So how would I send information to the reserved server securely?

I can think of 2 ways:

  1. MessagingService
  2. TeleportData.

Now, I know the second one is for the client, but suppose you made the clients all send the information to the server upon teleporting to it. You can then compare all the clients data and make sure the server has the correct info.

That way, if a hacker were to try to fake the votes, it would not work, as it does not match up with everyone else’s.

Of course, the messaging service method would probably be simpler. I just had the teleportdata idea for a while, but I never tested it.

I think (TeleportData) would be best for this, you can send a string with the map name and the ReservedServer will take that map from a list if the string is valid.

local function TeleportToPrivateServerWithInformation(targetPlaceId: number, players)
	local TeleportService = game:GetService("TeleportService")
	-- TeleportPartyAsync() won't work because it cannot teleport to private servers, but it returns JobId
	TeleportService:TeleportToPrivateServer(targetPlaceId, TeleportService:ReserveServer(targetPlaceId), players) --> Void
end

Here is the problem. I need to use private server but I also would need to get JobId so I could send the message to the right server.

Wouldn’t be prone to exploiting? Just take a look.

This function retrieves a teleport setting saved using TeleportService:SetTeleportSetting using the given key. This method is intended for use on the client only and should not be used on the server.

https://developer.roblox.com/en-us/api-reference/function/TeleportService/GetTeleportSetting

I didn’t read over the page at all (nor do I know anything about this) however couldn’t you check if all the players map is the same? For example by sending all the players maps to the server, and load the avarage map? Dunno how this would work but it’s all i can really think of lmfao

1 Like

I answered a question like this a while ago. See:

MessagingService is a poor choice for this kind of work because of the last point as raised in OP, knowing when the server is ready to receive the message and if the server containing the data will still be alive by the time players arrive in the reserved server.

2 Likes

So I looked over your posts, so I can assume that data that is encrypted with SHA256 is safe because it’s salted and only server knows the secret? The only way I could think of exploiting this would be attempting to guess the secret but that would be almost impossible if I generated some very long secret such as

h4ZnUg8FsdjXGGRtgWbzHgsz7p3cCGNmJBcJpP5ybdC5fT6UMX4tx232k2xSyEvUvTtdJ822tPeEZbGmxmGPU3XBJ5yLGeYe7X88uTHEwP2h3Hh9zCzzAREmgTTjkzWm

So I also assume the steps are:

Oh and btw the link is not working for the SHA256.lua module. Should I use this instead?

So if I put all of this together, is this the right code to begin with?

local TeleportService = game:GetService("TeleportService")
local Sha256 = require(ServerScriptService.SHA256)
local Secret = "password123" -- Nothing to steal here :)
local DateFormat = "!*t"

local function TeleportToPrivateServerWithInformation(targetPlaceId: number, players: any, data: any)
	local notAfter = os.time(os.date(DateFormat))
	
	local passport = {
		notAfter = notAfter,
		data = data,
		hash = Sha256(notAfter.. data.. Secret)
	}
	
	local teleportOptions = Instance.new("TeleportOptions")
	teleportOptions:SetTeleportData(passport)
	teleportOptions.ReservedServerAccessCode = TeleportService:ReserveServer(targetPlaceId)
	teleportOptions.ShouldReserveServer = true
	
	TeleportService:TeleportAsync(targetPlaceId, players, teleportOptions)
end

local function GetTeleportInformation(passport: any)
	local hash = Sha256(passport.notAfter.. passport.data.. Secret)
	if passport.hash ~= hash then return end
	if not (passport.notAfter + 120 > os.time(DateFormat)) then return end
	return passport.data
end

Most of the information and explanation is in the post if you’re trying to use the additional teleport data security measure, but more or less the strong part of the hashing is the server salt. It doesn’t have to be incredibly long but “random” enough that it’d be hard to bruteforce. Even better if you can periodically change it by hand.

A misconception in your workflow is having a decryption step. Hashing is not meant to be an encryption-decryption workflow and you can likewise see that I do no such thing in the pseudocode and neither does the explanation suggest that. If you ever found a way to unhash SHA256, you should tell someone immediately, that’s a huge security vulnerability.

The hashing is meant for comparison to the end server. The goal here is that the sending server should be creating a hash of the data that you want to send and the receiving server will rebuild the hash on its own end to check the integrity of the hash. This is primarily where the expiry timer and the salting shine in terms of securing teleport data because they contribute in the hash’s make.

There’s no need to assume the steps since the steps are already included in the post.

As for the SHA256 module, I didn’t know that one was taken down. There’s another repository that contains the same script originally found at that Gist, can’t post it though because attempting to do so is resulting in an HTTP 403 here on the forum*. That being said, any pure Lua SHA256 implementation will work, the main thing you need to make sure is that it generates the hash properly when run on Roblox.

* Look for /MaHuJa/CC-scripts/blob/master/sha256.lua.

1 Like

https://developer.roblox.com/en-us/api-reference/event/TeleportService/LocalPlayerArrivedFromTeleport

The thread is quite old and still there’s no specific answer.
You can easily get TeleportData using GetJoinData function.

1 Like